diff options
Diffstat (limited to 'sw/source/filter/ww1')
-rw-r--r-- | sw/source/filter/ww1/fltshell.cxx | 2081 | ||||
-rw-r--r-- | sw/source/filter/ww1/makefile.mk | 93 | ||||
-rw-r--r-- | sw/source/filter/ww1/w1class.cxx | 1248 | ||||
-rw-r--r-- | sw/source/filter/ww1/w1class.hxx | 1599 | ||||
-rw-r--r-- | sw/source/filter/ww1/w1filter.cxx | 2028 | ||||
-rw-r--r-- | sw/source/filter/ww1/w1par.cxx | 139 | ||||
-rw-r--r-- | sw/source/filter/ww1/w1par.hxx | 45 | ||||
-rw-r--r-- | sw/source/filter/ww1/w1sprm.cxx | 690 | ||||
-rw-r--r-- | sw/source/filter/ww1/w1struct.hxx | 853 |
9 files changed, 8776 insertions, 0 deletions
diff --git a/sw/source/filter/ww1/fltshell.cxx b/sw/source/filter/ww1/fltshell.cxx new file mode 100644 index 000000000000..8ea2525b75d4 --- /dev/null +++ b/sw/source/filter/ww1/fltshell.cxx @@ -0,0 +1,2081 @@ +/* -*- 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + +#include <ctype.h> +#include <hintids.hxx> +#include <hints.hxx> +#include <svtools/filter.hxx> + +#include <vcl/graph.hxx> +#include <svl/urihelper.hxx> +#include <editeng/boxitem.hxx> +#include <editeng/boxitem.hxx> +#include <editeng/wghtitem.hxx> +#include <editeng/cmapitem.hxx> +#include <editeng/cntritem.hxx> +#include <editeng/postitem.hxx> +#include <editeng/crsditem.hxx> +#include <svl/stritem.hxx> +#include <unotools/charclass.hxx> +#include <txtftn.hxx> +#include <fmtpdsc.hxx> +#include <fmtftn.hxx> +#include <fmtanchr.hxx> +#include <fmtrfmrk.hxx> +#include <fmtclds.hxx> +#include <fmtfld.hxx> +#include <fmtfsize.hxx> +#include <fmthdft.hxx> +#include <fmtcntnt.hxx> +#include <redline.hxx> +#include <pam.hxx> +#include <doc.hxx> +#include <ndtxt.hxx> +#include <frmatr.hxx> +#include <fldbas.hxx> // RES_SETEXPFLD +#include <charatr.hxx> // class SwFmtRefMark +#include <swtable.hxx> // class SwTableLines, ... +#include <tox.hxx> +#include <expfld.hxx> // SwExpField +#include <section.hxx> // class SwSection +#include <tblsel.hxx> // class SwSelBoxes +#include <pagedesc.hxx> +#include <docsh.hxx> // class SwDocSh +#include <fltshell.hxx> +#include <viewsh.hxx> +#include <shellres.hxx> + + +#define MAX_FIELDLEN 64000 + +using namespace com::sun::star; + +static SwCntntNode* GetCntntNode(SwDoc* pDoc, SwNodeIndex& rIdx, BOOL bNext) +{ + SwCntntNode* pCNd = pDoc->GetNodes()[ rIdx ]->GetCntntNode(); + if(!pCNd && 0 == (pCNd = bNext ? pDoc->GetNodes().GoNext(&rIdx) + : pDoc->GetNodes().GoPrevious(&rIdx))) + { + pCNd = bNext ? pDoc->GetNodes().GoPrevious(&rIdx) + : pDoc->GetNodes().GoNext(&rIdx); + OSL_ENSURE(pCNd, "kein ContentNode gefunden"); + } + return pCNd; +} + +// ------ Stack-Eintrag fuer die gesamten - Attribute vom Text ----------- +SwFltStackEntry::SwFltStackEntry(const SwPosition& rStartPos, SfxPoolItem* pHt ) : + nMkNode(rStartPos.nNode, -1), + nPtNode(nMkNode) +{ + // Anfang vom Bereich merken + nMkCntnt = rStartPos.nContent.GetIndex(); + pAttr = pHt; // speicher eine Kopie vom Attribut + bOld = FALSE; // used for marking Attributes *before* skipping field results + bLocked = TRUE; // locke das Attribut --> darf erst + bCopied = FALSE; // gesetzt werden, wenn es wieder geunlocked ist + bConsumedByField = FALSE; +} + +SwFltStackEntry::SwFltStackEntry(const SwFltStackEntry& rEntry) : + nMkNode(rEntry.nMkNode), + nPtNode(rEntry.nPtNode) +{ + pAttr = rEntry.pAttr->Clone(); + nMkCntnt= rEntry.nMkCntnt; + bOld = rEntry.bOld; + bLocked = bCopied = TRUE; // when rEntry were NOT bLocked we would never have been called + bConsumedByField = rEntry.bConsumedByField; +} + + +SwFltStackEntry::~SwFltStackEntry() +{ + // Attribut kam zwar als Pointer, wird aber hier geloescht + if (pAttr) + delete pAttr; +} + +void SwFltStackEntry::SetEndPos(const SwPosition& rEndPos) +{ + // Attribut freigeben und das Ende merken. + // Alles mit USHORT's, weil sonst beim Einfuegen von neuem Text an der + // Cursor-Position auch der Bereich vom Attribut weiter + // verschoben wird. + // Das ist aber nicht das gewollte! + bLocked = FALSE; // freigeben und das ENDE merken + nPtNode = rEndPos.nNode.GetIndex()-1; + nPtCntnt = rEndPos.nContent.GetIndex(); +} + +BOOL SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, BOOL bCheck ) +{ + // wird ueberhaupt ein Bereich umspannt ?? + // - ist kein Bereich, dann nicht returnen wenn am Anfang vom Absatz + // - Felder aussortieren, koennen keinen Bereich haben !! + if ( + nMkNode.GetIndex() == nPtNode.GetIndex() && nMkCntnt == nPtCntnt && + nPtCntnt && RES_TXTATR_FIELD != pAttr->Which() + ) + { + return FALSE; + } + + // !!! Die Content-Indizies beziehen sich immer auf den Node !!! + rRegion.GetPoint()->nNode = nMkNode.GetIndex() + 1; + SwCntntNode* pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, TRUE); + rRegion.GetPoint()->nContent.Assign(pCNd, nMkCntnt); + rRegion.SetMark(); + if( nMkNode != nPtNode ) + { + rRegion.GetPoint()->nNode = nPtNode.GetIndex() + 1; + pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, FALSE); + } + rRegion.GetPoint()->nContent.Assign(pCNd, nPtCntnt); +#if OSL_DEBUG_LEVEL > 1 + OSL_ENSURE( CheckNodesRange( rRegion.Start()->nNode, + rRegion.End()->nNode, TRUE ), + "Attribut oder AEhnliches ueber Bereichs-Grenzen" ); +#endif + if( bCheck ) + return CheckNodesRange( rRegion.Start()->nNode, + rRegion.End()->nNode, TRUE ); + else + return TRUE; +} + +SwFltControlStack::SwFltControlStack(SwDoc* pDo, ULONG nFieldFl) + : nFieldFlags(nFieldFl), pDoc(pDo), bIsEndStack(false) +{ +} + + +SwFltControlStack::~SwFltControlStack() +{ + OSL_ENSURE(!Count(), "noch Attribute auf dem Stack"); +} + +// MoveAttrs() ist fuer folgendes Problem: +// Wenn ueber den Stack ein Feld wie z.B. "Variable setzen" gesetzt wird, +// verschiebt sich der Text um ein \xff - Zeichen, und alle folgenden +// Attribute stimmen in ihrer Position nicht mehr. +// Dann muss MoveAttrs() nach dem Setzen des Attributes ins Doc gerufen werden, +// so dass alle Attribut-Positionen, +// die im selben Absatz weiter hinten stehen, um 1 Zeichen weiter +// nach rechts verschoben werden. +void SwFltControlStack::MoveAttrs( const SwPosition& rPos ) +{ + USHORT nCnt = static_cast< USHORT >(Count()); + SwFltStackEntry* pEntry; + ULONG nPosNd = rPos.nNode.GetIndex(); + USHORT nPosCt = rPos.nContent.GetIndex() - 1; + + for (USHORT i=0; i < nCnt; i++){ + pEntry = (*this)[ i ]; + if(( pEntry->nMkNode.GetIndex() + 1 == nPosNd ) + &&( pEntry->nMkCntnt >= nPosCt )){ + pEntry->nMkCntnt++; + OSL_ENSURE( pEntry->nMkCntnt + <= pDoc->GetNodes()[nPosNd]->GetCntntNode()->Len(), + "Attribut-Anfang hinter Zeilenende" ); + } + if(( pEntry->nPtNode.GetIndex() + 1 == nPosNd ) + &&( pEntry->nPtCntnt >= nPosCt )){ + pEntry->nPtCntnt++; + OSL_ENSURE( pEntry->nPtCntnt + <= pDoc->GetNodes()[nPosNd]->GetCntntNode()->Len(), + "Attribut-Ende hinter Zeilenende" ); + } + } +} + +void SwFltControlStack::MarkAllAttrsOld() +{ + USHORT nCnt = static_cast< USHORT >(Count()); + for (USHORT i=0; i < nCnt; i++) + (*this)[ i ]->bOld = TRUE; +} + +void SwFltControlStack::NewAttr(const SwPosition& rPos, const SfxPoolItem & rAttr ) +{ + SwFltStackEntry *pTmp = new SwFltStackEntry(rPos, rAttr.Clone() ); + USHORT nWhich = pTmp->pAttr->Which(); + SetAttr(rPos, nWhich);// Ende von evtl. gleichen Attributen auf dem Stack + // Setzen, damit sich die Attribute nicht auf + // dem Stack haeufen + maEntries.push_back(pTmp); +} + +void SwFltControlStack::DeleteAndDestroy(Entries::size_type nCnt) +{ + OSL_ENSURE(nCnt < maEntries.size(), "Out of range!"); + if (nCnt < maEntries.size()) + { + myEIter aElement = maEntries.begin() + nCnt; + delete *aElement; + maEntries.erase(aElement); + } +} + +// SwFltControlStack::StealAttr() loescht Attribute des angegebenen Typs vom Stack. +// Als nAttrId sind erlaubt: 0 fuer alle, oder ein spezieller Typ. +// Damit erscheinen sie nicht in der Doc-Struktur. Dabei werden nur die +// Attribute entfernt, die im selben Absatz wie pPos stehen. +// Wird fuer Grafik-Apos -> Grafiken benutzt. +void SwFltControlStack::StealAttr(const SwPosition* pPos, USHORT nAttrId /* = 0 */) +{ + USHORT nCnt = static_cast< USHORT >(Count()); + + SwFltStackEntry* pEntry; + + while (nCnt) + { + nCnt --; + pEntry = (*this)[ nCnt ]; + if (pEntry->nPtNode.GetIndex()+1 == pPos->nNode.GetIndex() && + (!nAttrId || nAttrId == pEntry->pAttr->Which())) + DeleteAndDestroy(nCnt); // loesche aus dem Stack + } +} + +// SwFltControlStack::KillUnlockedAttr() loescht alle Attribute vom Stack, +// welche punktuell auf pPos aufgespannt sind. +// Damit erscheinen sie nicht in der Doc-Struktur. +// Wird im WW Import benoetigt zum ignorieren der auf dem 0x0c Section- +// Break-Symbol gesetzten Attribute. +void SwFltControlStack::KillUnlockedAttrs(const SwPosition& pPos) +{ + SwNodeIndex aAktNode( pPos.nNode, -1 ); + USHORT nAktIdx = pPos.nContent.GetIndex(); + + USHORT nCnt = static_cast< USHORT >(Count()); + SwFltStackEntry* pEntry; + while( nCnt ) + { + nCnt --; + pEntry = (*this)[ nCnt ]; + if( !pEntry->bOld + && !pEntry->bLocked + && (pEntry->nMkNode == aAktNode) + && (pEntry->nMkCntnt == nAktIdx ) + && (pEntry->nPtNode == aAktNode) + && (pEntry->nPtCntnt == nAktIdx )) + { + DeleteAndDestroy( nCnt ); // loesche aus dem Stack + } + } +} + +// Alle gelockten Attribute freigeben (unlocken) und das Ende setzen, +// alle anderen im Document setzen und wieder aus dem Stack loeschen +// Returned, ob das gesuchte Attribut / die gesuchten Attribute +// ueberhaupt auf dem Stack standen +void SwFltControlStack::SetAttr(const SwPosition& rPos, USHORT nAttrId, + BOOL bTstEnde, long nHand, BOOL consumedByField ) +{ + OSL_ENSURE(!nAttrId || + (POOLATTR_BEGIN <= nAttrId && POOLATTR_END > nAttrId) || + (RES_FLTRATTR_BEGIN <= nAttrId && RES_FLTRATTR_END > nAttrId), + "Falsche Id fuers Attribut"); + + USHORT nCnt = static_cast< USHORT >(Count()); + + SwFltStackEntry* pEntry; + + for (USHORT i=0; i < nCnt; i++) + { + pEntry = (*this)[ i ]; + if (pEntry->bLocked) + { + // setze das Ende vom Attribut + bool bF = false; + if (!nAttrId ){ + bF = true; + }else if( nAttrId == pEntry->pAttr->Which()){ + if( nAttrId != RES_FLTR_BOOKMARK ){ // Handle abfragen + bF = true; + }else if( nHand == ((SwFltBookmark*)(pEntry->pAttr))->GetHandle() ) + { + bF = true; + } + } + if (bF) { + pEntry->bConsumedByField = consumedByField; + pEntry->SetEndPos(rPos); + } + continue; + } + + // ist die Endposition die Cursor-Position, dann noch nicht + // ins Dokument setzen, es muss noch Text folgen; + // ausser am Dokumentende. (Attribut-Expandierung !!) + // Beim Ende-Stack niemals ausser am DocEnde reinsetzen + if (bTstEnde) + { + if (bIsEndStack || pEntry->nPtNode.GetIndex()+1 == + rPos.nNode.GetIndex()) + continue; + } + SetAttrInDoc(rPos, pEntry); + DeleteAndDestroy(i); // loesche aus dem Stack + i--; nCnt--; // Danach rutschen alle folgenden nach unten + } +} + +static void MakePoint(SwFltStackEntry* pEntry, SwDoc* pDoc, SwPaM& rRegion) +{ + // der Anker ist der Point vom Pam. Dieser wird beim Einfugen + // von Text usw. veraendert; darum wird er auf dem Stack + // gespeichert. Das Attribut muss nur noch im Format + // gesetzt werden. + rRegion.DeleteMark(); + rRegion.GetPoint()->nNode = pEntry->nMkNode.GetIndex() + 1; + SwCntntNode* pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, TRUE); + rRegion.GetPoint()->nContent.Assign(pCNd, pEntry->nMkCntnt); +} + +// MakeBookRegionOrPoint() ist wie MakeRegionOrPoint, aber die besonderen +// Beschraenkungen von Bookmarks in Tabellen werden beachtet. +// ( Anfang und Ende muessen in selber Zelle sein ) +static void MakeBookRegionOrPoint(SwFltStackEntry* pEntry, SwDoc* pDoc, + SwPaM& rRegion, BOOL bCheck ) +{ + if (pEntry->MakeRegion(pDoc, rRegion, bCheck )){ + const SwNodes& rNds = pDoc->GetNodes(); + if( rNds[rRegion.GetPoint()->nNode]->FindTableBoxStartNode() + != rNds[rRegion.GetMark()->nNode]->FindTableBoxStartNode() ){ + rRegion.Exchange(); // Ungueltiger Bereich + rRegion.DeleteMark(); // -> beide auf Mark + } + }else{ + MakePoint(pEntry, pDoc, rRegion); + } +} + +#if OSL_DEBUG_LEVEL > 1 +extern BOOL CheckNodesRange( const SwNodeIndex& rStt, + const SwNodeIndex& rEnd, BOOL bChkSection ); +#endif + +// IterateNumrulePiece() sucht von rTmpStart bis rEnd den ersten +// fuer Numrules gueltigen Bereich heraus. +// +// rNds sind die Doc-Nodes +// rEnd ist Bereichs-Ende, +// rTmpStart ist ReinRaus-Parameter: Anfang des zu untersuchenden Bereiches rein, +// Anfang des gueltigen Bereichs raus +// rTmpEnd ist raus-Parameter +// Return-Bool ist TRUE fuer gueltigen Bereich +static BOOL IterateNumrulePiece( const SwNodeIndex& rEnd, + SwNodeIndex& rTmpStart, SwNodeIndex& rTmpEnd ) +{ + while( ( rTmpStart <= rEnd ) + && !( rTmpStart.GetNode().IsTxtNode() ) ) // suche gueltigen Anfang + rTmpStart++; + + rTmpEnd = rTmpStart; + while( ( rTmpEnd <= rEnd ) + && ( rTmpEnd.GetNode().IsTxtNode() ) ) // suche gueltiges Ende + 1 + rTmpEnd++; + + rTmpEnd--; // gueltiges Ende + + return rTmpStart <= rTmpEnd; // gueltig ? +} + +void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos, SwFltStackEntry* pEntry) +{ + SwPaM aRegion( rTmpPos ); + + switch(pEntry->pAttr->Which()) + { + case RES_FLTR_ANCHOR: + { + SwFrmFmt* pFmt = ((SwFltAnchor*)pEntry->pAttr)->GetFrmFmt(); + if (pFmt != NULL) + { + MakePoint(pEntry, pDoc, aRegion); + SwFmtAnchor aAnchor(pFmt->GetAnchor()); + aAnchor.SetAnchor(aRegion.GetPoint()); + pFmt->SetFmtAttr(aAnchor); + // Damit die Frames bei Einfuegen in existierendes Doc + // erzeugt werden (erst nach Setzen des Ankers!): + if(pDoc->GetRootFrm() + && (FLY_AT_PARA == pFmt->GetAnchor().GetAnchorId())) + { + pFmt->MakeFrms(); + } + } + } + break; + case RES_FLTR_STYLESHEET: + break; + case RES_TXTATR_FIELD: + break; + case RES_TXTATR_TOXMARK: + break; + case RES_FLTR_NUMRULE: // Numrule 'reinsetzen + { + const String& rNumNm = ((SfxStringItem*)pEntry->pAttr)->GetValue(); + SwNumRule* pRul = pDoc->FindNumRulePtr( rNumNm ); + if( pRul ) + { + if( pEntry->MakeRegion(pDoc, aRegion, TRUE)) + { + SwNodeIndex aTmpStart( aRegion.Start()->nNode ); + SwNodeIndex aTmpEnd( aTmpStart ); + SwNodeIndex& rRegEndNd = aRegion.End()->nNode; + while( IterateNumrulePiece( rRegEndNd, + aTmpStart, aTmpEnd ) ) + { + SwPaM aTmpPam( aTmpStart, aTmpEnd ); + // --> OD 2008-03-17 #refactorlists# + // no start of a new list + pDoc->SetNumRule( aTmpPam, *pRul, false ); + // <-- + + aTmpStart = aTmpEnd; // Start fuer naechstes Teilstueck + aTmpStart++; + } + } + else + pDoc->DelNumRule( rNumNm ); + } + } + break; + case RES_FLTR_NUMRULE_NUM: + break; + case RES_FLTR_BOOKMARK: // eigentlich nur fuer den Ende-Stack + { + SwFltBookmark* pB = (SwFltBookmark*)pEntry->pAttr; + const String& rName = ((SwFltBookmark*)pEntry->pAttr)->GetName(); + + if (IsFlagSet(BOOK_TO_VAR_REF)) + { + if (pB->IsPgRef() && !pB->IsRef()) + { + // XRefs und Bookmarks sind bereits geUpcased + MakeBookRegionOrPoint(pEntry, pDoc, aRegion, TRUE); + pDoc->InsertPoolItem(aRegion, SwFmtRefMark(rName), 0); + } + else if( !pB->IsOnlyRef() ) + { + SwFieldType* pFT = pDoc->GetFldType(RES_SETEXPFLD, rName, false); + if (!pFT) + { // FieldType anlegen + SwSetExpFieldType aS(pDoc, rName, nsSwGetSetExpType::GSE_STRING); + pFT = pDoc->InsertFldType(aS); + } + SwSetExpField aFld((SwSetExpFieldType*)pFT, + pB->GetValSys()); + aFld.SetSubType( nsSwExtendedSubType::SUB_INVISIBLE ); + MakePoint(pEntry, pDoc, aRegion); + pDoc->InsertPoolItem(aRegion, SwFmtFld(aFld), 0); + MoveAttrs( *(aRegion.GetPoint()) ); + } + } + if( !pB->IsOnlyRef() && + ( !IsFlagSet(HYPO) || IsFlagSet(BOOK_AND_REF) ) && !pEntry->bConsumedByField) + { + MakeBookRegionOrPoint(pEntry, pDoc, aRegion, TRUE); + pDoc->getIDocumentMarkAccess()->makeMark( aRegion, rName, IDocumentMarkAccess::BOOKMARK); + } + } + break; + case RES_FLTR_TOX: + { + MakePoint(pEntry, pDoc, aRegion); + + SwPosition* pPoint = aRegion.GetPoint(); + + SwFltTOX* pTOXAttr = (SwFltTOX*)pEntry->pAttr; + + // test if on this node there had been a pagebreak BEFORE the + // tox attribut was put on the stack + SfxItemSet aBkSet( pDoc->GetAttrPool(), RES_PAGEDESC, RES_BREAK ); + SwCntntNode* pNd = 0; + if( !pTOXAttr->HadBreakItem() || !pTOXAttr->HadPageDescItem() ) + { + pNd = pPoint->nNode.GetNode().GetCntntNode(); + if( pNd ) + { + const SfxItemSet* pSet = pNd->GetpSwAttrSet(); + const SfxPoolItem* pItem; + if( pSet ) + { + if( !pTOXAttr->HadBreakItem() + && SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, FALSE, &pItem ) ) + { + aBkSet.Put( *pItem ); + pNd->ResetAttr( RES_BREAK ); + } + if( !pTOXAttr->HadPageDescItem() + && SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, FALSE, &pItem ) ) + { + aBkSet.Put( *pItem ); + pNd->ResetAttr( RES_PAGEDESC ); + } + } + } + } + + delete pTOXAttr->GetBase(); + + // set (aboved saved and removed) the break item at the node following the TOX + if( aBkSet.Count() ) + pNd->SetAttr( aBkSet ); + } + break; + case RES_FLTR_SECTION: + MakePoint(pEntry, pDoc, aRegion); // bislang immer Point==Mark + pDoc->InsertSwSection(aRegion, + *(static_cast<SwFltSection*>(pEntry->pAttr))->GetSectionData(), + 0, 0, false); + delete (((SwFltSection*)pEntry->pAttr)->GetSectionData()); + break; + case RES_FLTR_REDLINE: + { + if (pEntry->MakeRegion(pDoc, aRegion, TRUE)) + { + pDoc->SetRedlineMode((RedlineMode_t)( nsRedlineMode_t::REDLINE_ON + | nsRedlineMode_t::REDLINE_SHOW_INSERT + | nsRedlineMode_t::REDLINE_SHOW_DELETE )); + SwFltRedline& rFltRedline = *((SwFltRedline*)pEntry->pAttr); + + if( USHRT_MAX != rFltRedline.nAutorNoPrev ) + { + SwRedlineData aData(rFltRedline.eTypePrev, + rFltRedline.nAutorNoPrev, + rFltRedline.aStampPrev, + aEmptyStr, + 0 + ); + pDoc->AppendRedline(new SwRedline(aData, aRegion), true); + } + SwRedlineData aData(rFltRedline.eType, + rFltRedline.nAutorNo, + rFltRedline.aStamp, + aEmptyStr, + 0 + ); + pDoc->AppendRedline( new SwRedline(aData, aRegion), true ); + pDoc->SetRedlineMode((RedlineMode_t)( nsRedlineMode_t::REDLINE_NONE + | nsRedlineMode_t::REDLINE_SHOW_INSERT + | nsRedlineMode_t::REDLINE_SHOW_DELETE )); + } + } + break; + default: + if (pEntry->MakeRegion(pDoc, aRegion, FALSE)) + { + pDoc->InsertPoolItem(aRegion, *pEntry->pAttr, 0); + } + break; + } +} + +SfxPoolItem* SwFltControlStack::GetFmtStackAttr(USHORT nWhich, USHORT * pPos) +{ + SwFltStackEntry* pEntry; + USHORT nSize = static_cast< USHORT >(Count()); + + while (nSize) + { + // ist es das gesuchte Attribut ? (gueltig sind nur gelockte, + // also akt. gesetzte Attribute!!) + if ((pEntry = (*this)[ --nSize ])->bLocked && + pEntry->pAttr->Which() == nWhich) + { + if (pPos) + *pPos = nSize; + return (SfxPoolItem*)pEntry->pAttr; // Ok, dann Ende + } + } + return 0; +} + +const SfxPoolItem* SwFltControlStack::GetFmtAttr(const SwPosition& rPos, USHORT nWhich) +{ + SfxPoolItem* pHt = GetFmtStackAttr(nWhich); + if (pHt) + return (const SfxPoolItem*)pHt; + + // im Stack ist das Attribut nicht vorhanden, also befrage das Dokument + SwCntntNode * pNd = pDoc->GetNodes()[ rPos.nNode ]->GetCntntNode(); + + if (!pNd) // kein ContentNode, dann das dflt. Attribut + return &pDoc->GetAttrPool().GetDefaultItem(nWhich); + return &pNd->GetAttr(nWhich); +} + +void SwFltControlStack::Delete(const SwPaM &rPam) +{ + const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End(); + + if( !rPam.HasMark() || *pStt >= *pEnd ) + return; + + SwNodeIndex aStartNode(pStt->nNode, -1); + USHORT nStartIdx = pStt->nContent.GetIndex(); + SwNodeIndex aEndNode(pEnd->nNode, -1); + USHORT nEndIdx = pEnd->nContent.GetIndex(); + + //We don't support deleting content that is over one node, or removing a node. + OSL_ENSURE(aEndNode == aStartNode, "nodes must be the same, or this method extended"); + if (aEndNode != aStartNode) + return; + + for (USHORT nSize = static_cast< USHORT >(Count()); nSize > 0;) + { + SwFltStackEntry* pEntry = (*this)[--nSize]; + + bool bEntryStartAfterSelStart = + (pEntry->nMkNode == aStartNode && pEntry->nMkCntnt >= nStartIdx); + + bool bEntryStartBeforeSelEnd = + (pEntry->nMkNode == aEndNode && pEntry->nMkCntnt <= nEndIdx); + + bool bEntryEndAfterSelStart = false; + bool bEntryEndBeforeSelEnd = false; + if (!pEntry->bLocked) + { + bEntryEndAfterSelStart = + (pEntry->nPtNode == aStartNode && pEntry->nPtCntnt >= nStartIdx); + + bEntryEndBeforeSelEnd = + (pEntry->nPtNode == aEndNode && pEntry->nPtCntnt <= nEndIdx); + } + + bool bTotallyContained = false; + if ( + bEntryStartAfterSelStart && bEntryStartBeforeSelEnd && + bEntryEndAfterSelStart && bEntryEndBeforeSelEnd + ) + { + bTotallyContained = true; + } + + if (bTotallyContained) + { + //after start, before end, delete + DeleteAndDestroy(nSize); + continue; + } + + xub_StrLen nCntntDiff = nEndIdx - nStartIdx; + + //to be adjusted + if (bEntryStartAfterSelStart) + { + if (bEntryStartBeforeSelEnd) + { + //move start to new start + pEntry->nMkNode = aStartNode; + pEntry->nMkCntnt = nStartIdx; + } + else + pEntry->nMkCntnt = pEntry->nMkCntnt - nCntntDiff; + } + + if (bEntryEndAfterSelStart) + { + if (bEntryEndBeforeSelEnd) + { + pEntry->nPtNode = aStartNode; + pEntry->nPtCntnt = nStartIdx; + } + else + pEntry->nPtCntnt = pEntry->nPtCntnt - nCntntDiff; + } + + //That's what locked is, end equal to start, and nPtCntnt is invalid + if (pEntry->bLocked) + pEntry->nPtNode = pEntry->nMkNode; + } +} + +//------ hier stehen die Methoden von SwFltAnchor ----------- +SwFltAnchor::SwFltAnchor(SwFrmFmt* pFmt) : + SfxPoolItem(RES_FLTR_ANCHOR), pFrmFmt(pFmt) +{ + pClient = new SwFltAnchorClient(this); + pFrmFmt->Add(pClient); +} + +SwFltAnchor::SwFltAnchor(const SwFltAnchor& rCpy) : + SfxPoolItem(RES_FLTR_ANCHOR), pFrmFmt(rCpy.pFrmFmt) +{ + pClient = new SwFltAnchorClient(this); + pFrmFmt->Add(pClient); +} + +SwFltAnchor::~SwFltAnchor() +{ + delete pClient; +} + +void SwFltAnchor::SetFrmFmt(SwFrmFmt * _pFrmFmt) +{ + pFrmFmt = _pFrmFmt; +} + +const SwFrmFmt * SwFltAnchor::GetFrmFmt() const +{ + return pFrmFmt; +} + +SwFrmFmt * SwFltAnchor::GetFrmFmt() +{ + return pFrmFmt; +} + +int SwFltAnchor::operator==(const SfxPoolItem& rItem) const +{ + return pFrmFmt == ((SwFltAnchor&)rItem).pFrmFmt; +} + +SfxPoolItem* __EXPORT SwFltAnchor::Clone(SfxItemPool*) const +{ + return new SwFltAnchor(*this); +} + +// SwFltAnchorClient + +SwFltAnchorClient::SwFltAnchorClient(SwFltAnchor * pFltAnchor) +: m_pFltAnchor(pFltAnchor) +{ +} + +void SwFltAnchorClient::Modify(SfxPoolItem *, SfxPoolItem * pNew) +{ + if (pNew->Which() == RES_FMT_CHG) + { + SwFmtChg * pFmtChg = dynamic_cast<SwFmtChg *> (pNew); + + if (pFmtChg != NULL) + { + SwFrmFmt * pFrmFmt = dynamic_cast<SwFrmFmt *> (pFmtChg->pChangedFmt); + + if (pFrmFmt != NULL) + m_pFltAnchor->SetFrmFmt(pFrmFmt); + } + } +} + +//------ hier stehen die Methoden von SwFltRedline ----------- +int SwFltRedline::operator==(const SfxPoolItem& rItem) const +{ + return this == &rItem; +} + +SfxPoolItem* SwFltRedline::Clone( SfxItemPool* ) const +{ + return new SwFltRedline(*this); +} + +//------ hier stehen die Methoden von SwFltBookmark ----------- +SwFltBookmark::SwFltBookmark( const String& rNa, const String& rVa, + long nHand, BOOL bOnlyR ) + : SfxPoolItem(RES_FLTR_BOOKMARK), nHandle(nHand), aName(rNa), aVal(rVa), + bOnlyRef(bOnlyR), bRef(FALSE), bPgRef(FALSE) +{ + // eSrc: CHARSET_DONTKNOW fuer keine UEbersetzung bei operator << + // Upcase wird immer gemacht. + // bei XXXStack.NewAttr(...) wird nie eine UEbersetzung vorgenommen. + // ansonsten: uebergebener Src-Charset fuer aName + // im Filter eingestellter Src-Charset fuer aVal ( Text ) +} + +SwFltBookmark::SwFltBookmark(const SwFltBookmark& rCpy) + : SfxPoolItem(RES_FLTR_BOOKMARK), + nHandle(rCpy.nHandle), + aName(rCpy.aName), + aVal(rCpy.aVal), + bOnlyRef(rCpy.bOnlyRef), + bRef(rCpy.bRef), + bPgRef(rCpy.bPgRef) +{ +} + +int SwFltBookmark::operator==(const SfxPoolItem& rItem) const +{ + return (aName == ((SwFltBookmark&)rItem).aName) + && (nHandle == ((SwFltBookmark&)rItem).nHandle); +} + +SfxPoolItem* SwFltBookmark::Clone(SfxItemPool*) const +{ + return new SwFltBookmark(*this); +} + +//------ hier stehen die Methoden von SwFltTOX ----------- + +SwFltTOX::SwFltTOX(SwTOXBase* pBase, USHORT _nCols) + : SfxPoolItem(RES_FLTR_TOX), pTOXBase(pBase), nCols( _nCols ), + bHadBreakItem( FALSE ), bHadPageDescItem( FALSE ) +{ +} + +SwFltTOX::SwFltTOX(const SwFltTOX& rCpy) + : SfxPoolItem(RES_FLTR_TOX), pTOXBase(rCpy.pTOXBase), nCols( rCpy.nCols ), + bHadBreakItem( rCpy.bHadBreakItem ), bHadPageDescItem( rCpy.bHadPageDescItem ) +{ +} + +int SwFltTOX::operator==(const SfxPoolItem& rItem) const +{ + return pTOXBase == ((SwFltTOX&)rItem).pTOXBase; +} + +SfxPoolItem* SwFltTOX::Clone(SfxItemPool*) const +{ + return new SwFltTOX(*this); +} + +//------ hier stehen die Methoden von SwFltSwSection ----------- + +SwFltSection::SwFltSection(SwSectionData *const pSect) + : SfxPoolItem(RES_FLTR_SECTION) + , m_pSection(pSect) +{ +} + +SwFltSection::SwFltSection(const SwFltSection& rCpy) + : SfxPoolItem(RES_FLTR_SECTION) + , m_pSection(rCpy.m_pSection) +{ +} + +int SwFltSection::operator==(const SfxPoolItem& rItem) const +{ + return m_pSection == ((SwFltSection&)rItem).m_pSection; +} + +SfxPoolItem* __EXPORT SwFltSection::Clone(SfxItemPool*) const +{ + return new SwFltSection(*this); +} + +/////////////////////////////////////////////////////////////////////// +// +// hier beginnt der von mdt erzeugte code. dieser ist eine shell auf +// der writer-seite nach moeglichkeit bald fuer alle filter. die ganze +// schwierigkeit, texte & formatattribute einzufuegen, die positionen +// zu verwalten, styles & kopf/fuszzeilen etc. +// + +//////////////////////////////////////////////////////////// SwFltShell +SwFltShell::SwFltShell(SwDoc* pDoc, SwPaM& rPaM, const String& rBaseURL, BOOL bNew, ULONG nFieldFl) : + pCurrentPageDesc(0), + pSavedPos(0), + eSubMode(None), + nAktStyle(0), + aStack(pDoc, nFieldFl), + aEndStack(pDoc, nFieldFl), + pPaM(new SwPaM(*(rPaM.GetPoint()))), + sBaseURL(rBaseURL), + nPageDescOffset(GetDoc().GetPageDescCnt()), + eSrcCharSet(RTL_TEXTENCODING_MS_1252), + bNewDoc(bNew), + bStdPD(FALSE), + bProtect(FALSE) +{ + memset( pColls, 0, sizeof( pColls ) ); + pOutDoc = new SwFltOutDoc( *pDoc, pPaM, aStack, aEndStack ); + pOut = pOutDoc; + + if( !bNewDoc ){ // in ein Dokument einfuegen ? + // Da immer ganze Zeile eingelesen werden, muessen + // evtl. Zeilen eingefuegt / aufgebrochen werden + const SwPosition* pPos = pPaM->GetPoint(); + const SwTxtNode* pSttNd = pPos->nNode.GetNode().GetTxtNode(); + USHORT nCntPos = pPos->nContent.GetIndex(); + if( nCntPos && pSttNd->GetTxt().Len() ) + // EinfuegePos nicht in leerer Zeile + pDoc->SplitNode( *pPos, false ); // neue Zeile erzeugen + if( pSttNd->GetTxt().Len() ){ // EinfuegePos nicht am Ende der Zeile + pDoc->SplitNode( *pPos, false ); // neue Zeile + pPaM->Move( fnMoveBackward ); // gehe in leere Zeile + } + + // verhinder das Einlesen von Tabellen in Fussnoten / Tabellen + ULONG nNd = pPos->nNode.GetIndex(); + BOOL bReadNoTbl = 0 != pSttNd->FindTableNode() || + ( nNd < pDoc->GetNodes().GetEndOfInserts().GetIndex() && + pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() < nNd ); + if( bReadNoTbl ) + pOutDoc->SetReadNoTable(); + } + pCurrentPageDesc = &((SwPageDesc&)const_cast<const SwDoc *>(pDoc) + ->GetPageDesc( 0 )); // Standard + +} + +SwFltShell::~SwFltShell() +{ + USHORT i; + + if (eSubMode == Style) + EndStyle(); + if( pOutDoc->IsInTable() ) // falls nicht ordentlich abgeschlossen + EndTable(); + if( pOutDoc->IsInFly() ) + EndFly(); + + GetDoc().SetUpdateExpFldStat(true); + GetDoc().SetInitDBFields(TRUE); + aStack.SetAttr(*pPaM->GetPoint(), 0, FALSE); + aStack.SetAttr(*pPaM->GetPoint(), 0, FALSE); + aEndStack.SetAttr(*pPaM->GetPoint(), 0, FALSE); + aEndStack.SetAttr(*pPaM->GetPoint(), 0, FALSE); + if( bProtect ){ // Das ganze Doc soll geschuetzt sein + + SwDoc& rDoc = GetDoc(); + // 1. SectionFmt und Section anlegen + SwSectionFmt* pSFmt = rDoc.MakeSectionFmt( 0 ); + SwSectionData aSectionData( CONTENT_SECTION, String::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM("PMW-Protect") )); + aSectionData.SetProtectFlag( true ); + // 2. Start- und EndIdx suchen + const SwNode* pEndNd = &rDoc.GetNodes().GetEndOfContent(); + SwNodeIndex aEndIdx( *pEndNd, -1L ); + const SwStartNode* pSttNd = pEndNd->StartOfSectionNode(); + SwNodeIndex aSttIdx( *pSttNd, 1L ); // +1 -> hinter StartNode + // Section einfuegen + // Section einfuegen + rDoc.GetNodes().InsertTextSection( + aSttIdx, *pSFmt, aSectionData, 0, &aEndIdx, false ); + + if( !IsFlagSet(SwFltControlStack::DONT_HARD_PROTECT) ){ + SwDocShell* pDocSh = rDoc.GetDocShell(); + if( pDocSh ) + pDocSh->SetReadOnlyUI( TRUE ); + } + } + // Pagedescriptoren am Dokument updaten (nur so werden auch die + // linken Seiten usw. eingestellt). + + GetDoc().ChgPageDesc( 0, + const_cast<const SwDoc &>(GetDoc()). + GetPageDesc( 0 )); // PageDesc "Standard" + for (i=nPageDescOffset;i<GetDoc().GetPageDescCnt();i++) + { + const SwPageDesc& rPD = const_cast<const SwDoc &>(GetDoc()). + GetPageDesc(i); + GetDoc().ChgPageDesc(i, rPD); + } + + delete pPaM; + for (i=0; i<sizeof(pColls)/sizeof(*pColls); i++) + if( pColls[i] ) + delete pColls[i]; + delete pOutDoc; +} + +SwFltShell& SwFltShell::operator << ( const String& rStr ) +{ + OSL_ENSURE(eSubMode != Style, "char insert while in style-mode"); + GetDoc().InsertString( *pPaM, rStr ); + return *this; +} + +void SwFltShell::ConvertUStr( String& rInOut ) +{ + GetAppCharClass().toUpper( rInOut ); +} + +// QuoteString() wandelt CRs abhaengig von nFieldIniFlags in '\n' oder "\0x0d" +String SwFltShell::QuoteStr( const String& rIn ) +{ + String sOut( rIn ); + BOOL bAllowCr = aStack.IsFlagSet( SwFltControlStack::ALLOW_FLD_CR ); + + for( xub_StrLen n = 0; n < sOut.Len(); ++n ) + { + switch( sOut.GetChar( n ) ) + { + case 0x0a: + sOut.Erase( n, 1 ); // 0xd 0xa wird zu \n + break; + + case 0x0b: + case 0x0c: + case 0x0d: + if( bAllowCr ) + sOut.SetChar( n, '\n' ); + break; + } + } + return sOut; +} + +SwFltShell& SwFltShell::operator << ( const sal_Unicode c ) +{ + OSL_ENSURE( eSubMode != Style, "char insert while in style-mode"); + GetDoc().InsertString( *pPaM, c ); + return *this; +} + +SwFltShell& SwFltShell::AddError( const sal_Char* pErr ) +{ + String aName( String::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM( "ErrorTag" ))); + SwFieldType* pFT = GetDoc().GetFldType( RES_SETEXPFLD, aName, false ); + if( pFT == 0) + { + SwSetExpFieldType aS(&GetDoc(), aName, nsSwGetSetExpType::GSE_STRING); + pFT = GetDoc().InsertFldType(aS); + } + SwSetExpField aFld( (SwSetExpFieldType*)pFT, + String::CreateFromAscii( pErr )); + //, VVF_INVISIBLE + GetDoc().InsertPoolItem(*pPaM, SwFmtFld(aFld), 0); + return *this; +} + +SwFltShell& SwFltShell::operator << (Graphic& rGraphic) +{ + // embedded Grafik !! + GetDoc().Insert(*pPaM, aEmptyStr, aEmptyStr, &rGraphic, NULL, NULL, NULL); + return *this; +} + +void SwFltShell::NextParagraph() +{ + GetDoc().AppendTxtNode(*pPaM->GetPoint()); +} + +void SwFltShell::NextPage() +{ + NextParagraph(); + GetDoc().InsertPoolItem(*pPaM, + SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK), 0); +} + +SwFltShell& SwFltShell::AddGraphic( const String& rPicName ) +{ + // embedded: + GraphicFilter* pFilter = GraphicFilter::GetGraphicFilter(); + Graphic aGraphic; + // one of: GFF_NOT GFF_BMP GFF_GIF GFF_JPG GFF_PCD GFF_PCX GFF_PNG + // GFF_TIF GFF_XBM GFF_DXF GFF_MET GFF_PCT GFF_SGF GFF_SVM GFF_WMF + // GFF_SGV GFF_XXX + INetURLObject aDir( + URIHelper::SmartRel2Abs( + INetURLObject(GetBaseURL()), rPicName, + URIHelper::GetMaybeFileHdl()) ); + switch (pFilter->ImportGraphic(aGraphic, aDir)) + { + case GRFILTER_OK: + *this << aGraphic; + break; + case GRFILTER_OPENERROR: + case GRFILTER_IOERROR: + case GRFILTER_FORMATERROR: + case GRFILTER_VERSIONERROR: + case GRFILTER_FILTERERROR: + case GRFILTER_ABORT: + case GRFILTER_TOOBIG: + default: + AddError( "picture import error" ); + break; + } + return *this; +} + +SwFltShell& SwFltShell::SetStyle( USHORT nStyle ) +{ + SwFltFormatCollection* p = pColls[ nStyle ]; + + if (p) + { + if( !pOutDoc->IsInTable() && nStyle != nAktStyle ) + { + if( pColls[nAktStyle]->IsInFly() && pOutDoc->IsInFly() ) + pOutDoc->EndFly(); + if( p->IsInFly() ) + p->BeginStyleFly( pOutDoc ); + } + GetDoc().SetTxtFmtColl(*pPaM, p->GetColl()); + nAktStyle = nStyle; + } + else + { + OSL_ENSURE( FALSE, "Ungueltiger SwFltStyleCode" ); + } + return *this; +} + +SwFltShell& SwFltShell::operator << (SwFltBookmark& aBook) +{ + ConvertUStr( aBook.aName ); + aBook.aVal = QuoteStr(aBook.aVal); + aEndStack.NewAttr(*pPaM->GetPoint(), aBook); + return *this; +} + +void SwFltShell::SetBookEnd(long nHandle) +{ + aEndStack.SetAttr( *pPaM->GetPoint(), RES_FLTR_BOOKMARK, TRUE, nHandle ); +} + +SwFltShell& SwFltShell::EndItem( USHORT nAttrId ) +{ + switch( nAttrId ) + { + case RES_FLTR_BOOKMARK: + OSL_ENSURE( FALSE, "Falscher Aufruf fuer Bookmark-Ende" ); + break; + + case RES_FLTR_TOX: + aEndStack.SetAttr(*pPaM->GetPoint(), nAttrId); + break; + + default: + aStack.SetAttr(*pPaM->GetPoint(), nAttrId); + break; + } + return *this; +} + +SwFltShell& SwFltShell::operator << (const SwField& rField) +{ + GetDoc().InsertPoolItem(*pPaM, SwFmtFld(rField), 0); + return *this; +} + +/*virtual*/ SwFltOutBase& SwFltOutDoc::operator << (const SfxPoolItem& rItem) +{ + rStack.NewAttr(*pPaM->GetPoint(), rItem); + return *this; +} + +/*virtual*/ SwFltOutBase& SwFltFormatCollection::operator << + (const SfxPoolItem& rItem) +{ + pColl->SetFmtAttr(rItem); + return *this; +} + +const SfxPoolItem& SwFltOutDoc::GetAttr(USHORT nWhich) +{ + return *rStack.GetFmtAttr(*pPaM->GetPoint(), nWhich); +} + +const SfxPoolItem& SwFltFormatCollection::GetAttr(USHORT nWhich) +{ + return GetColl()->GetFmtAttr(nWhich); // mit Parents +} + +// GetNodeOrStyAttr holt Attribute fuer Toggle- und Modify-Attribute: +// Bei Formatdefinitionen aus dem altuellen Style mit Parents +// sonst aus dem Node mit Parents +// Im Stack wird nicht nachgesehen + +const SfxPoolItem& SwFltOutDoc::GetNodeOrStyAttr(USHORT nWhich) +{ + SwCntntNode * pNd = GetDoc().GetNodes()[ pPaM->GetPoint()->nNode ] + ->GetCntntNode(); + if (pNd) // ContentNode: Attribut mit Parent + return pNd->GetAttr(nWhich); + else // kein ContentNode, dann das dflt. Attribut + return GetDoc().GetAttrPool().GetDefaultItem(nWhich); +} + +const SfxPoolItem& SwFltFormatCollection::GetNodeOrStyAttr(USHORT nWhich) +{ + return GetColl()->GetFmtAttr(nWhich); // mit Parents +} + +const SfxPoolItem& SwFltShell::GetNodeOrStyAttr(USHORT nWhich) +{ + return pOut->GetNodeOrStyAttr( nWhich ); +} + +const SfxPoolItem& SwFltShell::GetAttr(USHORT nWhich) +{ + return pOut->GetAttr( nWhich ); +} + +const SfxPoolItem& SwFltShell::GetFlyFrmAttr(USHORT nWhich) +{ + return pOut->GetFlyFrmAttr( nWhich ); +} + +SwFieldType* SwFltShell::GetSysFldType(USHORT eWhich) +{ + return GetDoc().GetSysFldType(eWhich); +} + +BOOL SwFltShell::GetWeightBold() +{ + return ((SvxWeightItem&)GetNodeOrStyAttr(RES_CHRATR_WEIGHT)).GetWeight() + != WEIGHT_NORMAL; +} + +BOOL SwFltShell::GetPostureItalic() +{ + return ((SvxPostureItem&)GetNodeOrStyAttr(RES_CHRATR_POSTURE)).GetPosture() + != ITALIC_NONE; +} + +BOOL SwFltShell::GetCrossedOut() +{ + return ((SvxCrossedOutItem&)GetNodeOrStyAttr(RES_CHRATR_CROSSEDOUT)) + .GetStrikeout() != STRIKEOUT_NONE; +} + +BOOL SwFltShell::GetContour() +{ + return ((SvxContourItem&)GetNodeOrStyAttr(RES_CHRATR_CONTOUR)).GetValue(); +} + +BOOL SwFltShell::GetCaseKapitaelchen() +{ + return ((SvxCaseMapItem&)GetNodeOrStyAttr(RES_CHRATR_CASEMAP)) + .GetCaseMap() == SVX_CASEMAP_KAPITAELCHEN; +} + +BOOL SwFltShell::GetCaseVersalien() +{ + return ((SvxCaseMapItem&)GetNodeOrStyAttr(RES_CHRATR_CASEMAP)) + .GetCaseMap() == SVX_CASEMAP_VERSALIEN; +} + +//------------------------------------------------------------------------- +// Tabellen +//------------------------------------------------------------------------- + +SwFltOutBase::~SwFltOutBase() +{ +} + +SwFltOutBase::SwFltOutBase(SwDoc& rDocu) + : rDoc(rDocu), eFlyAnchor(FLY_AT_PARA), bFlyAbsPos(false) +{ +} + +const SfxPoolItem& SwFltOutBase::GetCellAttr(USHORT nWhich) +{ + OSL_ENSURE(FALSE, "GetCellAttr ausserhalb von normalem Text"); + return GetDoc().GetAttrPool().GetDefaultItem(nWhich); +} + +BOOL SwFltOutBase::BeginTable() +{ + OSL_ENSURE(FALSE, "BeginTable ausserhalb von normalem Text"); + return FALSE; +} + +void SwFltOutBase::NextTableCell() +{ + OSL_ENSURE(FALSE, "NextTableCell ausserhalb von normalem Text"); +} + +void SwFltOutBase::NextTableRow() +{ + OSL_ENSURE(FALSE, "NextTableRow ausserhalb von normalem Text"); +} + +void SwFltOutBase::SetTableWidth(SwTwips /*nW*/) +{ + OSL_ENSURE(FALSE, "SetTableWidth ausserhalb von normalem Text"); +} + +void SwFltOutBase::SetTableOrient(sal_Int16 /*eOri*/) +{ + OSL_ENSURE(FALSE, "SetTableOrient ausserhalb von normalem Text"); +} + +void SwFltOutBase::SetCellWidth(SwTwips /*nWidth*/, USHORT /*nCell*/) +{ + OSL_ENSURE(FALSE, "SetCellWidth ausserhalb von normalem Text"); +} + +void SwFltOutBase::SetCellHeight(SwTwips /*nH*/) +{ + OSL_ENSURE(FALSE, "SetCellHeight ausserhalb von normalem Text"); +} + +void SwFltOutBase::SetCellBorder(const SvxBoxItem& /*rFmtBox*/, USHORT /*nCell*/) +{ + OSL_ENSURE(FALSE, "SetCellBorder ausserhalb von normalem Text"); +} + +void SwFltOutBase::SetCellSpace(USHORT /*nSp*/) +{ + OSL_ENSURE(FALSE, "SetCellSpace ausserhalb von normalem Text"); +} + +void SwFltOutBase::DeleteCell(USHORT /*nCell*/) +{ + OSL_ENSURE(FALSE, "DeleteCell ausserhalb von normalem Text"); +} + +void SwFltOutBase::EndTable() +{ + OSL_ENSURE(FALSE, "EndTable ausserhalb von normalem Text"); +} + +/*virtual*/ BOOL SwFltOutDoc::IsInTable() +{ + return pTable != 0; +}; + +BOOL SwFltOutDoc::BeginTable() +{ + if(bReadNoTbl) + return FALSE; + + if (pTable){ + OSL_ENSURE(FALSE, "BeginTable in Table"); + return FALSE; + } + // Alle Attribute schliessen, da sonst Attribute + // entstehen koennen, die in Flys reinragen + rStack.SetAttr( *pPaM->GetPoint(), 0, FALSE ); + rEndStack.SetAttr( *pPaM->GetPoint(), 0, FALSE ); + +// create table: + OSL_ENSURE(pTabSavedPos == NULL, "SwFltOutDoc"); + pTabSavedPos = new SwPosition(*pPaM->GetPoint()); + pTable = GetDoc().InsertTable( + SwInsertTableOptions( tabopts::HEADLINE_NO_BORDER, 1 ), + *pTabSavedPos, 1, 1, text::HoriOrientation::LEFT, 0, 0, FALSE, FALSE ); // TODO MULTIHEADER + nTableWidth = 0; + ((SwTable*)pTable)->LockModify(); // Nichts automatisch anpassen! +// set pam in 1. table cell + usTableX = + usTableY = 0; + SeekCell(usTableY, usTableX, TRUE); + return TRUE; +} + +SwTableBox* SwFltOutDoc::GetBox(USHORT ny, USHORT nx /*= USHRT_MAX */) +{ + if(!pTable){ + OSL_ENSURE(pTable, "GetBox ohne Tabelle"); + return 0; + } + if( nx == USHRT_MAX ) // aktuelle Zelle + nx = usTableX; + +// get structs to table cells + const SwTableLines* pTableLines = &pTable->GetTabLines(); + if(!pTableLines){ + OSL_ENSURE(FALSE, "SwFltOutDoc:GetBox:pTableLines"); + return 0; + } + if( ny >= pTableLines->Count() ){ // Notbremse + OSL_ENSURE( FALSE, "SwFltOutDoc:GetBox:ny >= Count()"); + ny = pTableLines->Count() - 1; + } + SwTableLine* pTableLine = (*pTableLines)[ny]; + if(!pTableLine){ + OSL_ENSURE(FALSE, "SwFltOutDoc:GetBox:pTableLine"); + return 0; + } + SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes(); + if(!pTableBoxes){ + OSL_ENSURE(FALSE, "SwFltOutDoc:GetBox:pTableBoxes"); + return 0; + } + if( nx >= pTableBoxes->Count() ){ // Notbremse + OSL_ENSURE(FALSE, "SwFltOutDoc:GetBox:nx >= Count()"); + nx = pTableBoxes->Count() - 1; + } + SwTableBox* pTableBox = (*pTableBoxes)[nx]; + + OSL_ENSURE(pTableBox != 0, "SwFltOutDoc:GetBox:pTableBox"); + return pTableBox; +} + +void SwFltOutDoc::NextTableCell() +{ + if(!pTable){ + OSL_ENSURE(pTable, "NextTableCell ohne Tabelle"); + return; + } + const SwTableLines* pTableLines = &pTable->GetTabLines(); + SwTableLine* pTableLine = (*pTableLines)[usTableY]; + SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes(); + SwTableBox* pTableBox = (*pTableBoxes)[usTableX]; + OSL_ENSURE(pTableBox != 0, "SwFltOutDoc:NextTableCell:pTableBox"); + if(!pTableBox) + return; +//#pragma message(__FILE__ "(?) : Sw's const problem") +// insert cells: + if (++usTableX >= pTableBoxes->Count()) + GetDoc().GetNodes().InsBoxen( + GetDoc().IsIdxInTbl(pPaM->GetPoint()->nNode), + pTableLine, + (SwTableBoxFmt*)pTableBox->GetFrmFmt(), + GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ), + 0, + pTableBoxes->Count()); + SeekCell(usTableY, usTableX, TRUE); + pTableBox = (*pTableBoxes)[usTableX]; + OSL_ENSURE(pTableBox != 0, "SwFltOutDoc:pTableBox"); + if(pTableBox) + (*pTableBoxes)[usTableX]->ClaimFrmFmt(); +} + +void SwFltOutDoc::NextTableRow() +{ + SwTableBox* pTableBox = GetBox(usTableY, 0); + if (pTableBox) + { +// duplicate row: + SwSelBoxes aSelBoxes; + aSelBoxes.Insert( pTableBox ); + GetDoc().InsertRow(aSelBoxes); + usTableX = 0; + SeekCell(++usTableY, usTableX, TRUE); + GetDoc().SetTxtFmtColl(*pPaM, + GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false )); + } +} + +void SwFltOutDoc::SetTableWidth(SwTwips nSwWidth) +{ + if(!pTable){ + OSL_ENSURE(pTable, "SetTableWidth ohne Tabelle"); + return; + } + OSL_ENSURE( nSwWidth > MINLAY, "Tabellenbreite <= MINLAY" ); + if( nSwWidth != nTableWidth ){ + if( nTableWidth ) // Nicht beim ersten Setzen + SplitTable(); + pTable->GetFrmFmt()->SetFmtAttr( SwFmtFrmSize(ATT_VAR_SIZE, nSwWidth)); + nTableWidth = nSwWidth; + } +} + +void SwFltOutDoc::SetTableOrient(sal_Int16 eOri) +{ + if(!pTable){ + OSL_ENSURE(pTable, "SetTableOrient ohne Tabelle"); + return; + } + pTable->GetFrmFmt()->SetFmtAttr( SwFmtHoriOrient( 0, eOri )); +} + +void SwFltOutDoc::SetCellWidth(SwTwips nWidth, USHORT nCell /* = USHRT_MAX */ ) +{ + if(!pTable){ + OSL_ENSURE(pTable, "SetCellWidth ohne Tabelle"); + return; + } + OSL_ENSURE( nWidth > MINLAY, "Tabellenzellenbreite <= MINLAY" ); + if (nWidth < MINLAY) + nWidth = MINLAY; + + SwTableBox* pTableBox = GetBox(usTableY, nCell); + if(pTableBox && pTableBox->GetFrmFmt() ){ + SwFmtFrmSize aFmtFrmSize(ATT_FIX_SIZE); + aFmtFrmSize.SetWidth(nWidth); + pTableBox->GetFrmFmt()->SetFmtAttr(aFmtFrmSize); + } +} + +void SwFltOutDoc::SetCellHeight(SwTwips nHeight) +{ + if(!pTable){ + OSL_ENSURE(pTable, "SetCellHeight ohne Tabelle"); + return; + } + + const SwTableLines* pTableLines = &pTable->GetTabLines(); + SwTableLine* pTableLine = (*pTableLines)[usTableY]; + SwFmtFrmSize aFmtFrmSize(ATT_MIN_SIZE, 0, 0); + if (nHeight < MINLAY) + nHeight = MINLAY; + aFmtFrmSize.SetHeight(nHeight); + pTableLine->GetFrmFmt()->SetFmtAttr(aFmtFrmSize); +} + +const SfxPoolItem& SwFltOutDoc::GetCellAttr(USHORT nWhich) +{ + if (!pTable){ + OSL_ENSURE(pTable, "GetCellAttr ohne Table"); + return GetDoc().GetAttrPool().GetDefaultItem(nWhich); + } + + SwTableBox* pTableBox = GetBox(usTableY, usTableX); + if(!pTableBox) + return GetDoc().GetAttrPool().GetDefaultItem(nWhich); + return pTableBox->GetFrmFmt()->GetFmtAttr( nWhich ); +} + +void SwFltOutDoc::SetCellBorder(const SvxBoxItem& rFmtBox, + USHORT nCell /* = USHRT_MAX */ ) +{ + SwTableBox* pTableBox = GetBox(usTableY, nCell); + if(pTableBox) + pTableBox->GetFrmFmt()->SetFmtAttr(rFmtBox); +} + +// nicht aktiviert !!! +void SwFltOutDoc::SetCellSpace(USHORT nDist) +{ + if(!pTable){ + OSL_ENSURE(pTable, "SetCellSpace ohne Tabelle"); + return; + } + SwTableBox* pTableBox = GetBox(usTableY, usTableX); + if(!pTableBox) + return; + + SvxBoxItem aFmtBox( *((SvxBoxItem*) + &pTableBox->GetFrmFmt()->GetFmtAttr( RES_BOX ))); + + // versteh ich nich, sven: if (!nDist) nDist = 18; // ca. 0.03 cm + if (nDist > 42) // max. 0.7 mm + nDist = 42; + else + if (nDist < MIN_BORDER_DIST) + nDist = MIN_BORDER_DIST; + aFmtBox.SetDistance(nDist); + pTableBox->GetFrmFmt()->SetFmtAttr(aFmtBox); +} + +void SwFltOutDoc::DeleteCell(USHORT nCell /* = USHRT_MAX */) +{ + SwTableBox* pTableBox = GetBox(usTableY, nCell); + if(pTableBox){ + SwSelBoxes aSelBoxes; + aSelBoxes.Insert( pTableBox ); + GetDoc().DeleteRowCol(aSelBoxes); + usTableX--; + } +} + +void SwFltOutDoc::SplitTable() +{ + if(!pTable) + { + OSL_ENSURE(pTable, "SplitTable ohne Tabelle"); + return; + } + SwTableBox* pAktBox = GetBox(usTableY, usTableX); + SwTableBox* pSplitBox = GetBox(usTableY - 1, 0); + GetDoc().GetNodes().SplitTable(SwNodeIndex(*pSplitBox->GetSttNd()), false); + pTable = &pAktBox->GetSttNd()->FindTableNode()->GetTable(); + usTableY = 0; +} + +void SwFltOutDoc::EndTable() +{ + if (!pTable){ + OSL_ENSURE(pTable, "EndTable ohne Table"); + return; + } + // Alle Attribute schliessen, da sonst Attribute + // entstehen koennen, die in Flys reinragen + rStack.SetAttr( *pPaM->GetPoint(), 0, FALSE ); + rEndStack.SetAttr( *pPaM->GetPoint(), 0, FALSE ); + + if (GetDoc().GetRootFrm()){ + SwTableNode* pTableNode = GetDoc().IsIdxInTbl( + pPaM->GetPoint()->nNode); + pTableNode->DelFrms(); + pTableNode->MakeFrms(&pPaM->GetPoint()->nNode); + } + + *pPaM->GetPoint() = *pTabSavedPos; // restore Cursor + delete pTabSavedPos; + pTabSavedPos = 0; + ((SwTable*)pTable)->UnlockModify(); // Test, nuetzt nichts gegen Assert + pTable = 0; + nTableWidth = 0; +} + +BOOL SwFltOutDoc::SeekCell(short nRow, short nCol, BOOL bPam) +{ +// get structs to table cells + const SwTableLines* pTableLines = &pTable->GetTabLines(); + SwTableLine* pTableLine = (*pTableLines)[usTableY]; + SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes(); + SwTableBox* pTableBox = (*pTableBoxes)[usTableX]; + + if ((USHORT)nRow >= pTableLines->Count()) + { + OSL_ENSURE((USHORT)nRow >= pTableLines->Count(), "SwFltOutDoc"); + return FALSE; + } + pTableLine = (*pTableLines)[nRow]; + pTableBoxes = &pTableLine->GetTabBoxes(); + if (nCol >= pTableBoxes->Count()) + return FALSE; + pTableBox = (*pTableBoxes)[nCol]; + if( !pTableBox->GetSttNd() ) + { + OSL_ENSURE(pTableBox->GetSttNd(), "SwFltOutDoc"); + return FALSE; + } + if(bPam) + { + pPaM->GetPoint()->nNode = pTableBox->GetSttIdx() + 1; + pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0); +//#pragma message(__FILE__ "(?) : Sw's const problem") +#if OSL_DEBUG_LEVEL > 1 + const SwTxtFmtColl* p = GetDoc().GetDfltTxtFmtColl(); + p = GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ); +#endif + GetDoc().SetTxtFmtColl(*pPaM, + GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false )); + } + return TRUE; +} + + +//----------------------------------------------------------------------------- +// Flys in SwFltOutBase +//----------------------------------------------------------------------------- + +SfxItemSet* SwFltOutBase::NewFlyDefaults() +{ +// Unbedingt noetige Standardwerte setzen ( falls diese Werte nicht +// spaeter explizit gesetzt werden ) + + SfxItemSet* p = new SfxItemSet( GetDoc().GetAttrPool(), + RES_FRMATR_BEGIN, RES_FRMATR_END-1 ); + SwFmtFrmSize aSz( ATT_VAR_SIZE, MINFLY, MINFLY ); + // Default: Breite 100% ( = PMW:Auto ) + aSz.SetWidthPercent( 100 ); // Hoehe: Auto + p->Put( aSz ); + p->Put( SwFmtHoriOrient( 0, text::HoriOrientation::NONE, text::RelOrientation::FRAME )); + return p; +} + +BOOL SwFltOutBase::BeginFly( RndStdIds eAnchor /*= FLY_AT_PARA*/, + BOOL bAbsolutePos /*= FALSE*/, + const SfxItemSet* +#if OSL_DEBUG_LEVEL > 1 + pMoreAttrs /*= 0*/ +#endif + ) +{ +#if OSL_DEBUG_LEVEL > 1 + OSL_ENSURE(!pMoreAttrs, "SwFltOutBase:BeginFly mit pMoreAttrs" ); +#endif + eFlyAnchor = eAnchor; + bFlyAbsPos = bAbsolutePos; // Bloedsinn eigentlich + return TRUE; +} + +/*virtual*/ void SwFltOutBase::SetFlyAnchor( RndStdIds eAnchor ) +{ + if( !IsInFly() ){ + OSL_ENSURE( FALSE, "SetFlyAnchor() ohne Fly" ); + return; + } + if ( eAnchor == FLY_AS_CHAR ){ + OSL_ENSURE( FALSE, "SetFlyAnchor( FLY_AS_CHAR ) nicht implementiert" ); + return; + } + SwFmtAnchor& rAnchor = (SwFmtAnchor&)GetFlyFrmAttr( RES_ANCHOR ); + rAnchor.SetType( eAnchor ); +} + +void SwFltOutBase::EndFly() +{ + if( bFlyAbsPos ){ + // hier muessen die absoluten Positionen am Fly noch in + // die Writer-Koordinaten umgerechnet werden. + } +} + +//----------------------------------------------------------------------------- +// Flys in SwFltDoc +//----------------------------------------------------------------------------- + +/* virtual */ BOOL SwFltOutDoc::IsInFly() +{ + return pFly != 0; +}; + +SwFrmFmt* SwFltOutDoc::MakeFly( RndStdIds eAnchor, SfxItemSet* pSet ) +{ + pFly = (SwFlyFrmFmt*)GetDoc().MakeFlySection( eAnchor, pPaM->GetPoint(), + pSet ); + return pFly; +} + +BOOL SwFltOutDoc::BeginFly( RndStdIds eAnchor, + BOOL bAbsolutePos , + const SfxItemSet* pMoreAttrs) + +{ + SwFltOutBase::BeginFly( eAnchor, bAbsolutePos, 0 ); + SfxItemSet* pSet = NewFlyDefaults(); + +// Alle Attribute schliessen, da sonst Attribute entstehen koennen, +// die in Flys reinragen + rStack.SetAttr( *pPaM->GetPoint(), 0, FALSE ); + rEndStack.SetAttr( *pPaM->GetPoint(), 0, FALSE ); + +// create Fly: + OSL_ENSURE(pFlySavedPos == NULL, "BeginFly in Fly"); // rekursiv geht noch nicht + pFlySavedPos = new SwPosition(*pPaM->GetPoint()); + + + SwFmtAnchor aAnchor( eAnchor, 1 ); + +// Wenn Fly-Attribute im Style waren, dann jetzt als Defaults reinsetzen + if (pMoreAttrs) + pSet->Put(*pMoreAttrs); + +// dieses NICHT bei Seitengebundenem Fly mit Seiten-NUMMER ! + aAnchor.SetAnchor(pPaM->GetPoint()); // braucht erstaunlicherweise + // den Stack nicht + + pSet->Put( aAnchor ); + SwFrmFmt* pF = MakeFly( eAnchor, pSet ); + delete pSet; + +// set pam in Fly + const SwFmtCntnt& rCntnt = pF->GetCntnt(); + OSL_ENSURE( rCntnt.GetCntntIdx(), "Kein Inhalt vorbereitet." ); + pPaM->GetPoint()->nNode = rCntnt.GetCntntIdx()->GetIndex() + 1; + SwCntntNode *pNode = pPaM->GetCntntNode(); + pPaM->GetPoint()->nContent.Assign( pNode, 0 ); + + return TRUE; +} + +/*virtual*/ void SwFltOutDoc::SetFlyFrmAttr(const SfxPoolItem& rAttr) +{ + if (pFly){ + pFly->SetFmtAttr( rAttr ); + }else{ + OSL_ENSURE(pFly, "SetFlyAttr ohne Doc-Fly"); + return; + } +} + +/*virtual*/ const SfxPoolItem& SwFltOutDoc::GetFlyFrmAttr(USHORT nWhich) +{ + if (pFly){ + return pFly->GetFmtAttr( nWhich ); + }else{ + OSL_ENSURE(pFly, "GetFlyAttr ohne Fly"); + return GetDoc().GetAttrPool().GetDefaultItem(nWhich); + } +} + +void SwFltOutDoc::EndFly() +{ + if( pTable ){ + OSL_ENSURE( FALSE, "SwFltOutDoc::EndFly() in Table" ); + return; + } + // Alle Attribute schliessen, da sonst Attribute + // entstehen koennen, die aus Flys rausragen + rStack.SetAttr( *pPaM->GetPoint(), 0, FALSE ); + rEndStack.SetAttr( *pPaM->GetPoint(), 0, FALSE ); + + *pPaM->GetPoint() = *pFlySavedPos; // restore Cursor + delete pFlySavedPos; + pFlySavedPos = 0; + SwFltOutBase::EndFly(); + pFly = 0; +} + +//----------------------------------------------------------------------------- +// Flys in SwFltFormatCollection +//----------------------------------------------------------------------------- +/*virtual*/ BOOL SwFltFormatCollection::IsInFly() +{ + return bHasFly; +}; + +/*virtual*/ void SwFltFormatCollection::SetFlyFrmAttr(const SfxPoolItem& rAttr) +{ + if (!pFlyAttrs) + pFlyAttrs = new SfxItemSet( GetDoc().GetAttrPool(), + RES_FRMATR_BEGIN, RES_FRMATR_END-1 ); + pFlyAttrs->Put( rAttr ); +} + +/*virtual*/ const SfxPoolItem& SwFltFormatCollection::GetFlyFrmAttr(USHORT nWhich) +{ + if( pFlyAttrs ) + return pFlyAttrs->Get( nWhich, FALSE ); + else + return GetDoc().GetAttrPool().GetDefaultItem(nWhich); +} + +BOOL SwFltFormatCollection::BeginFly( RndStdIds eAnchor, + BOOL bAbsolutePos, + const SfxItemSet* pMoreAttrs) + +{ + SwFltOutBase::BeginFly( eAnchor, bAbsolutePos, pMoreAttrs ); + bHasFly = TRUE; + return TRUE; +} + +void SwFltFormatCollection::EndFly() // Wird nie aufgerufen +{ +} + +BOOL SwFltFormatCollection::BeginStyleFly( SwFltOutDoc* pOutDoc ) +{ + OSL_ENSURE( pOutDoc, "BeginStyleFly ohne pOutDoc" ); + OSL_ENSURE( pOutDoc && !pOutDoc->IsInFly(), "BeginStyleFly in Fly" ); + if( pOutDoc && !pOutDoc->IsInFly() ) + return pOutDoc->BeginFly( eFlyAnchor, bFlyAbsPos, pFlyAttrs ); + else + return FALSE; +} + +//----------------------------------------------------------------------------- +// Flys in SwFltShell +//----------------------------------------------------------------------------- + +BOOL SwFltShell::BeginFly( RndStdIds eAnchor, + BOOL bAbsolutePos) + +{ + if (pOut->IsInFly()){ + OSL_ENSURE(FALSE, "BeginFly in Fly"); + return FALSE; + } + if (pOutDoc->IsInTable()){ + OSL_ENSURE(FALSE, "BeginFly in Table"); + return FALSE; + } + pOut->BeginFly( eAnchor, bAbsolutePos, pColls[nAktStyle]->GetpFlyAttrs() ); + eSubMode = Fly; + return TRUE; +} + +void SwFltShell::SetFlyXPos( short nXPos, sal_Int16 eHRel, + sal_Int16 eHAlign) +{ + SetFlyFrmAttr( SwFmtHoriOrient( nXPos, eHAlign, eHRel ) ); +} + +void SwFltShell::SetFlyYPos( short nYPos, sal_Int16 eVRel, + sal_Int16 eVAlign) +{ + SetFlyFrmAttr( SwFmtVertOrient( nYPos, eVAlign, eVRel ) ); +} + + +void SwFltShell::EndFly() +{ + if (!pOut->IsInFly()){ + OSL_ENSURE(FALSE, "EndFly ohne Fly"); + return; + } + if (pOutDoc->IsInTable()){ // Table verschraenkt mit Fly macht keinen Sinn + OSL_ENSURE(FALSE, "EndFly in Table ( verschraenkt )"); + EndTable(); // -> Table beenden + } + pOut->EndFly(); + eSubMode = None; +} + +//----------------------------------------------------------------------------- +// Fussnoten +//----------------------------------------------------------------------------- + +void SwFltShell::BeginFootnote() +{ + if( pOut->IsInFly() ){ // Passiert z.B. bei Fussnote in Fly + OSL_ENSURE(FALSE, "Fussnote in Fly nicht erlaubt"); + return; + } + if( pOutDoc->IsInTable() ){ + OSL_ENSURE(FALSE, "Fussnote in Table z.Zt. nicht erlaubt"); + return; + } + +// Alle Attribute schliessen, da sonst Attribute entstehen koennen, +// die in Fussnoten reinragen + aStack.SetAttr( *pPaM->GetPoint(), 0, FALSE ); +// EndStack erstmal nicht zwangs-Schliessen, damit Bookmarks ueber +// Fussnoten im PMW uebernommen werden + + SwFmtFtn aFtn; + GetDoc().InsertPoolItem(*pPaM, aFtn, 0); + OSL_ENSURE(pSavedPos == NULL, "SwFltShell"); + pSavedPos = new SwPosition(*pPaM->GetPoint()); + pPaM->Move(fnMoveBackward, fnGoCntnt); + SwTxtNode* pTxt = pPaM->GetNode()->GetTxtNode(); + SwTxtAttr *const pFN = pTxt->GetTxtAttrForCharAt( + pPaM->GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN); + if( !pFN ){ // Passiert z.B. bei Fussnote in Fly + OSL_ENSURE(pFN, "Probleme beim Anlegen des Fussnoten-Textes"); + return; + } + const SwNodeIndex* pStartIndex = ((SwTxtFtn*)pFN)->GetStartNode(); + OSL_ENSURE(pStartIndex, "Probleme beim Anlegen des Fussnoten-Textes"); + pPaM->GetPoint()->nNode = pStartIndex->GetIndex() + 1; + pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0); + eSubMode = Footnote; +} + +void SwFltShell::EndFootnote() +{ + if(!pSavedPos) + return; + // Alle Attribute schliessen, da sonst Attribute + // entstehen koennen, die aus Fussnoten rausragen + aStack.SetAttr( *pPaM->GetPoint(), 0, FALSE ); +// EndStack erstmal nicht zwangs-Schliessen, damit Bookmarks ueber +// Fussnoten im PMW uebernommen werden + + *pPaM->GetPoint() = *pSavedPos; // restore Cursor + delete pSavedPos; + pSavedPos = 0; +} + +void SwFltShell::BeginHeader(SwPageDesc* /*pPD*/) +{ + SwFrmFmt* pFmt = &pCurrentPageDesc->GetMaster(); + SwFrmFmt* pHdFtFmt; + pFmt->SetFmtAttr(SwFmtHeader(TRUE)); + pHdFtFmt = (SwFrmFmt*)pFmt->GetHeader().GetHeaderFmt(); + const SwNodeIndex* pStartIndex = pHdFtFmt->GetCntnt().GetCntntIdx(); + if (!pStartIndex) + return; + OSL_ENSURE(pSavedPos == NULL, "SwFltShell"); + pSavedPos = new SwPosition(*pPaM->GetPoint()); + pPaM->GetPoint()->nNode = pStartIndex->GetIndex() + 1; + pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0); + eSubMode = Header; +} + +void SwFltShell::BeginFooter(SwPageDesc* /*pPD*/) +{ + SwFrmFmt* pFmt = &pCurrentPageDesc->GetMaster(); + SwFrmFmt* pHdFtFmt; + pFmt->SetFmtAttr(SwFmtFooter(TRUE)); + pHdFtFmt = (SwFrmFmt*)pFmt->GetFooter().GetFooterFmt(); + const SwNodeIndex* pStartIndex = pHdFtFmt->GetCntnt().GetCntntIdx(); + if (!pStartIndex) + return; + OSL_ENSURE(pSavedPos == NULL, "SwFltShell"); + pSavedPos = new SwPosition(*pPaM->GetPoint()); + pPaM->GetPoint()->nNode = pStartIndex->GetIndex() + 1; + pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0); + eSubMode = Footer; +} + +void SwFltShell::EndHeaderFooter() +{ + *pPaM->GetPoint() = *pSavedPos; // restore Cursor + delete pSavedPos; + pSavedPos = 0; +} + +SwPageDesc* SwFltShell::MakePageDesc(SwPageDesc* pFirstPageDesc) +{ + if(bStdPD) // keine Neuen PageDescs + return pCurrentPageDesc; + + BOOL bFollow = (pFirstPageDesc != 0); + SwPageDesc* pNewPD; + USHORT nPos; + if (bFollow && pFirstPageDesc->GetFollow() != pFirstPageDesc) + return pFirstPageDesc; // Fehler: hat schon Follow +// Erkennung doppelter Namen fehlt noch (Wahrscheinlichkeit +// fuer dopp. Namen ist gering) + + nPos = GetDoc().MakePageDesc( ViewShell::GetShellRes()->GetPageDescName( + GetDoc().GetPageDescCnt(), FALSE, bFollow ), + pFirstPageDesc, FALSE ); + + pNewPD = &((SwPageDesc&)const_cast<const SwDoc &>(GetDoc()). + GetPageDesc(nPos)); + if (bFollow) + { // Dieser ist der folgende von pPageDesc + pFirstPageDesc->SetFollow(pNewPD); + pNewPD->SetFollow(pNewPD); + } + else + { + GetDoc().InsertPoolItem( *pPaM, SwFmtPageDesc( pNewPD ), 0 ); + } + pNewPD->WriteUseOn( // alle Seiten + (UseOnPage)(nsUseOnPage::PD_ALL | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE)); + return pNewPD; +} + +///////////////////////////////////////////////// SwFltFormatCollection +SwFltFormatCollection::SwFltFormatCollection( + SwDoc& _rDoc, RES_POOL_COLLFMT_TYPE nType ) : + SwFltOutBase(_rDoc), + pColl(_rDoc.GetTxtCollFromPool( static_cast< sal_uInt16 >(nType), false )), + pFlyAttrs( 0 ), + bHasFly( FALSE ) +{ + Reset(); // Default-Attrs loeschen und Auto-Flag +} + +SwFltFormatCollection::SwFltFormatCollection( + SwDoc& _rDoc, const String& rName ) : + SwFltOutBase(_rDoc), + pFlyAttrs( 0 ), + bHasFly( FALSE ) +{ + pColl = _rDoc.MakeTxtFmtColl(rName, (SwTxtFmtColl*)_rDoc.GetDfltTxtFmtColl()); + Reset(); // Default-Attrs loeschen und Auto-Flag +} + +void SwFltShell::NextStyle(USHORT nWhich, USHORT nNext) +{ + OSL_ENSURE(pColls[nWhich], "Next style for noexistent style" ); + OSL_ENSURE(pColls[nNext], "Next style to noexistent style" ); + if( pColls[nWhich] && pColls[nNext] ) + pColls[nWhich]->GetColl()->SetNextTxtFmtColl( + *pColls[nNext]->GetColl() ); +} + +// UpdatePageDescs muss am Ende des Einlesevorganges aufgerufen werden, damit +// der Writer den Inhalt der Pagedescs wirklich akzeptiert +void UpdatePageDescs(SwDoc &rDoc, sal_uInt16 nInPageDescOffset) +{ + // Pagedescriptoren am Dokument updaten (nur so werden auch die + // linken Seiten usw. eingestellt). + + // PageDesc "Standard" + rDoc.ChgPageDesc(0, const_cast<const SwDoc &>(rDoc).GetPageDesc(0)); + + // PageDescs "Konvert..." + for (sal_uInt16 i = nInPageDescOffset; i < rDoc.GetPageDescCnt(); ++i) + rDoc.ChgPageDesc(i, const_cast<const SwDoc &>(rDoc).GetPageDesc(i)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww1/makefile.mk b/sw/source/filter/ww1/makefile.mk new file mode 100644 index 000000000000..58930bdca9c7 --- /dev/null +++ b/sw/source/filter/ww1/makefile.mk @@ -0,0 +1,93 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=sw +TARGET=ww1 + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/inc$/swpre.mk +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/inc$/sw.mk + +.IF "$(mydebug)" != "" +CDEFS=$(CDEFS) -Dmydebug +.ENDIF + +# --- Files -------------------------------------------------------- + +EXCEPTIONSFILES= \ + $(SLO)$/fltshell.obj \ + $(SLO)$/w1filter.obj \ + $(SLO)$/w1par.obj \ + $(SLO)$/w1sprm.obj + +SLOFILES = \ + $(EXCEPTIONSFILES) \ + $(SLO)$/w1class.obj + + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + +run: alltar + +#copy all relevant files to a backupdir +bak: + copy ..\inc\fltshell.hxx backup + copy *.?xx backup + copy makefile* backup + copy vcs.cfg backup + copy ..\..\..\dump1\src\dump1.cxx backup + copy ..\..\..\dump1\src\makefile backup\makefile.dmp + copy ..\..\..\WNTMSCI\bin\makefile backup\makefile.bin + copy ..\..\..\UTIL\makefile backup\makefile.utl + copy s:\solenv\inc\wnt.mak backup + +# remove this filter from libs to avoid annoying effects +upgrade: + attrib -r *.?xx + attrib -r makefile.* + del ..\..\..\WNMSCI\LIB\ww1.lib + del ..\..\..\WNMSCI\DBO\w1*.obj + del ..\..\..\WNMSCI\DBO\fltshell.obj + del ..\..\..\WNMSCI\MISC + lib /nologo /REMOVE:..\..\..\WNTMSCI\obj\fltshell.obj /out:..\..\..\WNTMSCI\LIB\filter.lib ..\..\..\WNTMSCI\LIB\filter.lib + lib /nologo /REMOVE:..\..\..\WNTMSCI\obj\w1sprm.obj /out:..\..\..\WNTMSCI\LIB\filter.lib ..\..\..\WNTMSCI\LIB\filter.lib + lib /nologo /REMOVE:..\..\..\WNTMSCI\obj\w1filter.obj /out:..\..\..\WNTMSCI\LIB\filter.lib ..\..\..\WNTMSCI\LIB\filter.lib + lib /nologo /REMOVE:..\..\..\WNTMSCI\obj\w1class.obj /out:..\..\..\WNTMSCI\LIB\filter.lib ..\..\..\WNTMSCI\LIB\filter.lib + lib /nologo /REMOVE:..\..\..\WNTMSCI\obj\w1par.obj /out:..\..\..\WNTMSCI\LIB\filter.lib ..\..\..\WNTMSCI\LIB\filter.lib + copy backup\makefile.bin ..\..\..\WNTMSCI\bin\makefile + diff backup\makefile.utl ..\..\..\UTIL\makefile + diff s:\solenv\inc\wnt.mak backup + +zip: bak + pkzip c:\temp\ww1 backup\*.* + diff --git a/sw/source/filter/ww1/w1class.cxx b/sw/source/filter/ww1/w1class.cxx new file mode 100644 index 000000000000..2e999b73c0e2 --- /dev/null +++ b/sw/source/filter/ww1/w1class.cxx @@ -0,0 +1,1248 @@ +/* -*- 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +#include <string.h> +#include <tools/stream.hxx> + +#include <w1class.hxx> + + +#ifdef DUMP +static const sal_Char* pUnknown = "?"; +#define DUMPNAME(s) s +#else +#define DUMPNAME(s) 0 +#endif + +Ww1SingleSprm* Ww1Sprm::aTab[ 256 ]; +Ww1SingleSprm* Ww1Sprm::pSingleSprm = 0; + + + +/////////////////////////////////////////////////////////////////// Fib +Ww1Fib::Ww1Fib( SvStream& _rStream ) + : rStream(_rStream) +{ + bOK = 0 == rStream.Seek(0) && + rStream.Read( &aFib, sizeof( aFib )) == sizeof( aFib ); +} + +///////////////////////////////////////////////////////////// PlainText + +Ww1PlainText::Ww1PlainText(Ww1Fib& rWwFib, ULONG nFilePos, ULONG nCountBytes) + : rFib(rWwFib), ulFilePos(nFilePos), ulCountBytes(nCountBytes), + ulSeek(0), bOK(true) +{ +} + +sal_Unicode Ww1PlainText::operator [] ( ULONG ulOffset ) +{ + DBG_ASSERT( ulOffset<Count(), "Ww1PlainText" ); + sal_Unicode cRet; + sal_Char cRead; + if( rFib.GetStream().Seek( ulFilePos + ulOffset ) == ulFilePos+ulOffset && + rFib.GetStream().Read( &cRead, sizeof( cRead ) ) == sizeof( cRead ) ) + { + cRet = ByteString::ConvertToUnicode( cRead, RTL_TEXTENCODING_MS_1252 ); + } + else + cRet = ' '; + return cRet; +} + +String Ww1PlainText::GetText( ULONG ulOffset, ULONG nLen ) const +{ + String sRet; + ByteString aStr; + DBG_ASSERT(ulOffset+nLen<Count(), "Ww1PlainText"); + if( rFib.GetStream().Seek(ulFilePos+ulOffset) == ulFilePos+ulOffset && + rFib.GetStream().Read( aStr.AllocBuffer( static_cast< xub_StrLen >(nLen) ), nLen ) == nLen ) + sRet = String( aStr, RTL_TEXTENCODING_MS_1252 ); + return sRet; +} + +///////////////////////////////////////////////////////////////// Style +Ww1Style::Ww1Style() + : pPapx(0), pParent(0), stcBase(0), stcNext(0), bUsed(false) +{ +} + +Ww1Style::~Ww1Style() +{ + delete pPapx; +} + +void Ww1Style::SetDefaults(BYTE stc) +{ + if( 222 == stc ) + { + stcBase = 222; + stcNext = 222; + aChpx.hpsSet(20); + } +} + +USHORT Ww1Style::ReadName( BYTE*&p, USHORT& rnCountBytes, USHORT stc ) +{ + BYTE nCountBytes = SVBT8ToByte(p); + p++; + rnCountBytes--; + if( !nCountBytes ) // default + { + static const sal_Char* __READONLY_DATA names[] = + { + "W1 Null", //222 + "W1 Annotation reference", //223 + "W1 Annotation text", //224 + "W1 Table of contents 8", //225 + "W1 Table of contents 7", //226 + "W1 Table of contents 6", //227 + "W1 Table of contents 5", //228 + "W1 Table of contents 4", //229 + "W1 Table of contents 3", //230 + "W1 Table of contents 2", //231 + "W1 Table of contents 1", //232 + "W1 Index 7", //233 + "W1 Index 6", //234 + "W1 Index 5", //235 + "W1 Index 4", //236 + "W1 Index 3", //237 + "W1 Index 2", //238 + "W1 Index 1", //239 + "W1 Line number", //240 + "W1 Index heading", //241 + "W1 Footer", //242 + "W1 Header", //243 + "W1 Footnote reference", //244 + "W1 Footnote text", //245 + "W1 Heading 9", //246 + "W1 Heading 8", //247 + "W1 Heading 7", //248 + "W1 Heading 6", //249 + "W1 Heading 5", //250 + "W1 Heading 4", //251 + "W1 Heading 3", //252 + "W1 Heading 2", //253 + "W1 Heading 1", //254 + "W1 Normal indent" //255 + };//256 + + const sal_Char* pStr; + size_t nSize(stc); + if (!nSize) + pStr = "W1 Normal"; + else if (nSize - 222 >= sizeof(names) / sizeof(*names)) + pStr = "?"; + else + pStr = names[nSize-222]; + SetName(String(pStr, RTL_TEXTENCODING_MS_1252)); + } + else if( 255 > nCountBytes ) // unused + { + SetName( String( (sal_Char*)p, nCountBytes, RTL_TEXTENCODING_MS_1252 )); + p += nCountBytes; + DBG_ASSERT(rnCountBytes>=nCountBytes, "Ww1Style"); + rnCountBytes = rnCountBytes - nCountBytes; + } + return 0; +} + +USHORT Ww1Style::ReadChpx( BYTE*&p, USHORT& rnCountBytes ) +{ + USHORT nCountBytes = SVBT8ToByte(p); + p++; + rnCountBytes--; + if (nCountBytes != 255 // unused + && nCountBytes != 0) // default + { + if (nCountBytes > sizeof(aChpx)) + nCountBytes = sizeof(aChpx); + memcpy( &aChpx, p, nCountBytes ); + p += nCountBytes; + DBG_ASSERT(rnCountBytes>=nCountBytes, "Ww1Style"); + rnCountBytes = rnCountBytes - nCountBytes; + } + return 0; +} + +USHORT Ww1Style::ReadPapx(BYTE*&p, USHORT& rnCountBytes) +{ + USHORT nCountBytes = SVBT8ToByte(p); + p++; + rnCountBytes--; + if (nCountBytes != 255) + { + pPapx = new Ww1SprmPapx(p, nCountBytes); + p += nCountBytes; + DBG_ASSERT(rnCountBytes>=nCountBytes, "Ww1Style"); + rnCountBytes = rnCountBytes - nCountBytes; + } + else + pPapx = new Ww1SprmPapx(p, 0); + return 0; +} + +USHORT Ww1Style::ReadEstcp(BYTE*&p, USHORT& rnCountBytes) +{ + stcNext = SVBT8ToByte(p); + p++; + rnCountBytes--; + stcBase = SVBT8ToByte(p); + p++; + DBG_ASSERT(rnCountBytes>0, "Ww1Style"); + rnCountBytes--; + return 0; +} + +//////////////////////////////////////////////////////////// StyleSheet +Ww1StyleSheet::Ww1StyleSheet(Ww1Fib& _rFib) + : cstcStd(0), + rFib(_rFib), + bOK(FALSE) +{ + USHORT cbStshf = rFib.GetFIB().cbStshfGet(); + DBG_ASSERT(cbStshf>=17, "Ww1StyleSheet"); + for (USHORT stc=0;stc<Count();stc++) + { + aStyles[stc].SetParent(this); + aStyles[stc].SetDefaults((BYTE)stc); + } + BYTE* del = NULL; + if (rFib.GetStream().Seek(rFib.GetFIB().fcStshfGet()) + == (ULONG)rFib.GetFIB().fcStshfGet() + && (del = new BYTE[cbStshf]) != NULL + && rFib.GetStream().Read(del, cbStshf) == (ULONG)cbStshf) + { + BYTE* p = del; + cstcStd = SVBT16ToShort(p); + p += sizeof(SVBT16); + cbStshf -= sizeof(SVBT16); + ReadNames(p, cbStshf); + ReadChpx(p, cbStshf); + ReadPapx(p, cbStshf); + ReadEstcp(p, cbStshf); + DBG_ASSERT(cbStshf==0, "Ww1StyleSheet"); + bOK = cbStshf == 0; + } + delete [] del; +} + +USHORT Ww1StyleSheet::ReadNames( BYTE*& p, USHORT& rnCountBytes ) +{ + USHORT nCountBytes = SVBT16ToShort(p); + p += sizeof(SVBT16); + DBG_ASSERT(rnCountBytes>=nCountBytes, "Ww1StyleSheet"); + rnCountBytes = rnCountBytes - nCountBytes; + nCountBytes = nCountBytes - sizeof(SVBT16); + USHORT stcp = 0; + while (nCountBytes > 0) + { + USHORT stc = (stcp - cstcStd) & 255; + aStyles[stc].ReadName(p, nCountBytes, stc); + stcp++; + } + DBG_ASSERT(nCountBytes==0, "Ww1StyleSheet"); + return 0; +} + +USHORT Ww1StyleSheet::ReadChpx(BYTE*& p, USHORT& rnCountBytes) +{ + USHORT nCountBytes = SVBT16ToShort(p); + p += sizeof(SVBT16); + DBG_ASSERT(rnCountBytes>=nCountBytes, "Ww1StyleSheet"); + rnCountBytes = rnCountBytes - nCountBytes; + nCountBytes = nCountBytes - sizeof(SVBT16); + USHORT stcp = 0; + while (nCountBytes > 0) + { + USHORT stc = (stcp - cstcStd) & 255; + aStyles[stc].ReadChpx(p, nCountBytes); + stcp++; + } + DBG_ASSERT(nCountBytes == 0, "Ww1StyleSheet"); + return 0; +} + +USHORT Ww1StyleSheet::ReadPapx(BYTE*& p, USHORT& rnCountBytes) +{ + USHORT nCountBytes = SVBT16ToShort(p); + p += sizeof(SVBT16); + DBG_ASSERT(rnCountBytes>=nCountBytes, "Ww1StyleSheet"); + rnCountBytes = rnCountBytes - nCountBytes; + nCountBytes = nCountBytes - sizeof(SVBT16); + USHORT stcp = 0; + while (nCountBytes > 0) + { + USHORT stc = (stcp - cstcStd) & 255; + aStyles[stc].ReadPapx(p, nCountBytes); + stcp++; + } + DBG_ASSERT(nCountBytes == 0, "Ww1StyleSheet"); + return 0; +} + +USHORT Ww1StyleSheet::ReadEstcp(BYTE*& p, USHORT& rnCountBytes) +{ + USHORT iMac = SVBT16ToShort(p); + p += sizeof(SVBT16); + DBG_ASSERT(rnCountBytes>=sizeof(SVBT16), "Ww1StyleSheet"); + rnCountBytes -= sizeof(SVBT16); + for (USHORT stcp=0;stcp<iMac;stcp++) + { + USHORT stc = (stcp - cstcStd) & 255; + aStyles[stc].ReadEstcp(p, rnCountBytes); + } + DBG_ASSERT(rnCountBytes==0, "Ww1StyleSheet"); + return 0; +} + +///////////////////////////////////////////////////////////////// Fonts + +Ww1Fonts::Ww1Fonts(Ww1Fib& rInFib, ULONG nFieldFlgs) + : pFontA(0), rFib(rInFib), nFieldFlags(nFieldFlgs), nMax(0), bOK(false) +{ + if(rFib.GetFIB().cbSttbfffnGet() > 2 ) // ueberhaupt fonts? + { + SVBT16 nCountBytes; + DBG_ASSERT(rFib.GetFIB().cbSttbfffnGet() > sizeof(nCountBytes), "Ww1Fonts"); + if (rFib.GetStream().Seek(rFib.GetFIB().fcSttbfffnGet()) + == (ULONG)rFib.GetFIB().fcSttbfffnGet()) + if (rFib.GetStream().Read(nCountBytes, sizeof(nCountBytes)) + == sizeof(nCountBytes)) // Laenge steht hier nochmal + { + DBG_ASSERT(SVBT16ToShort(nCountBytes) + == rFib.GetFIB().cbSttbfffnGet(), "redundant-size missmatch"); + // hoffentlich sind sie immer gleich + W1_FFN* pA = (W1_FFN*)new char[rFib.GetFIB().cbSttbfffnGet() + - sizeof(nCountBytes)]; // Alloziere Font-Array + //~ Ww1: new-NULL + if (rFib.GetStream().Read(pA, rFib.GetFIB().cbSttbfffnGet() + - sizeof(nCountBytes)) == (ULONG)rFib.GetFIB().cbSttbfffnGet() + - sizeof(nCountBytes)) // lese alle Fonts + {} //nothing + + long nLeft = rFib.GetFIB().cbSttbfffnGet() + - sizeof(nCountBytes); // Zaehle, wieviele Fonts enthalten + W1_FFN* p = pA; + while (1) + { + USHORT nNextSiz; + nNextSiz = p->cbFfnM1Get() + 1; + if(nNextSiz > nLeft) + break; + nMax++; + nLeft -= nNextSiz; + if(nLeft < 1) // naechste Laenge muss gelesen werden koennen + break; + p = (W1_FFN *)(((char*)p) + nNextSiz); + } + if (nMax) + { + pFontA = new W1_FFN*[nMax]; // alloziere Index-Array + //~ Ww1: new-NULL + pFontA[0] = pA; // fuelle Index-Array + USHORT i; + for(i=1, p=pA; i<nMax; i++) + { + p = (W1_FFN*)(((char*)p) + p->cbFfnM1Get() + 1); + pFontA[i] = p; + } + } + else + pFontA = 0; // Keine Eintraege -> kein Array + } + } + bOK = TRUE; +} + +W1_FFN* Ww1Fonts::GetFFN(USHORT nNum) +{ + W1_FFN* pRet = NULL; + if (pFontA) + if (nNum < nMax) + pRet = pFontA[nNum]; + return pRet; +} + +/////////////////////////////////////////////////////////////////// DOP +Ww1Dop::Ww1Dop(Ww1Fib& _rFib) + : rFib(_rFib) +{ + long nRead; + memset(&aDop, 0, sizeof(aDop)); // set defaults + if(rFib.GetFIB().cbDopGet() >= sizeof(aDop)) + nRead = sizeof(aDop); + else + nRead = rFib.GetFIB().cbDopGet(); + bOK = rFib.GetStream().Seek(rFib.GetFIB().fcDopGet()) == + (ULONG)rFib.GetFIB().fcDopGet() && + rFib.GetStream().Read(&aDop, nRead) == (ULONG)nRead; +} + +/////////////////////////////////////////////////////////////// Picture +Ww1Picture::Ww1Picture(SvStream& rStream, ULONG ulFilePos) + : bOK(false), pPic(0) +{ + ulFilePos &= 0xffffff; //~ ww1: warum auch immer - im highbyte steht eine 5?!?! + SVBT32 lcb; + if (rStream.Seek(ulFilePos) == (ULONG)ulFilePos) + if (rStream.Read(&lcb, sizeof(lcb)) == (ULONG)sizeof(lcb)) + if (sizeof(int)>=4 || SVBT32ToUInt32(lcb) < 0x8000) //~ mdt: 64K & 16bit + if ((pPic = (W1_PIC*)(new BYTE[SVBT32ToUInt32(lcb)])) != NULL) + if (rStream.Seek(ulFilePos) == (ULONG)ulFilePos) + if (rStream.Read(pPic, SVBT32ToUInt32(lcb)) == (ULONG)SVBT32ToUInt32(lcb)) + { + DBG_ASSERT(pPic->cbHeaderGet()==sizeof(*pPic)-sizeof(pPic->rgb), "Ww1Picture"); + bOK = true; + } +} + +////////////////////////////////////////////////////////////////// Sprm +Ww1Sprm::Ww1Sprm(BYTE* x, USHORT _nCountBytes) + : p(NULL), + nCountBytes(_nCountBytes), + bOK(FALSE), + pArr(NULL), + count(0) +{ + if (nCountBytes == 0) + bOK = TRUE; + else + if ((p = new BYTE[nCountBytes]) != NULL) + { + memcpy(p, x, nCountBytes); + if (ReCalc()) + bOK = TRUE; + } +} + +Ww1Sprm::Ww1Sprm(SvStream& rStream, ULONG ulFilePos) + : p(NULL), + nCountBytes(0), + bOK(FALSE), + pArr(NULL), + count(0) +{ + SVBT8 x; + ByteToSVBT8(0, x); + if (rStream.Seek(ulFilePos) == (ULONG)ulFilePos) + if (rStream.Read(&x, sizeof(x)) == (ULONG)sizeof(x)) + if ((nCountBytes = SVBT8ToByte(x)) == 255 + || !nCountBytes + || (p = new BYTE[nCountBytes]) != NULL) + if (nCountBytes == 255 + || !nCountBytes + || rStream.Read(p, nCountBytes) == (ULONG)nCountBytes) + if (ReCalc()) + bOK = TRUE; +} + +Ww1Sprm::~Ww1Sprm() +{ + delete pArr; + delete p; +} + +USHORT Ww1SingleSprm::Size(BYTE* /*pSprm*/) +{ + return nCountBytes; +} + +USHORT Ww1SingleSprmTab::Size(BYTE* pSprm) // Doc 24/25, Fastsave-Sprm +{ + DBG_ASSERT(nCountBytes==0, "Ww1SingleSprmTab"); + USHORT nRet = sizeof(SVBT8); + USHORT nSize = SVBT8ToByte(pSprm); + if (nSize != 255) + nRet = nRet + nSize; + else + { + USHORT nDel = SVBT8ToByte(pSprm+1) * 4; + USHORT nIns = SVBT8ToByte(pSprm + 3 + nDel) * 3; + nRet += nDel + nIns; + } + DBG_ASSERT(nRet <= 354, "Ww1SingleSprmTab"); + if (nRet > 354) + nRet = 0; + return nRet; +} + +USHORT Ww1SingleSprmByteSized::Size(BYTE* pSprm) +{ + USHORT nRet; + nRet = SVBT8ToByte(pSprm); + nRet += sizeof(SVBT8); // var. l. byte-size + nRet = nRet + nCountBytes; + return nRet; +} + +USHORT Ww1SingleSprmWordSized::Size(BYTE* pSprm) +{ + USHORT nRet; + nRet = SVBT16ToShort(pSprm); + nRet += sizeof(SVBT16); // var. l. word-size + nRet = nRet + nCountBytes; + return nRet; +} + +static BYTE nLast = 0; +static BYTE nCurrent = 0; +USHORT Ww1Sprm::GetSize(BYTE nId, BYTE* pSprm) +{ + USHORT nL = 0; + nL = GetTab(nId).Size(pSprm); + nLast = nCurrent; + nCurrent = nId; + return nL; +} + +BOOL Ww1Sprm::Fill(USHORT index, BYTE& nId, USHORT& nL, BYTE*& pSprm) +{ + DBG_ASSERT(index < Count(), "Ww1Sprm"); + pSprm = p + pArr[index]; + nId = SVBT8ToByte(pSprm); + pSprm++; + nL = GetTab(nId).Size(pSprm); + return TRUE; +} + +BOOL Ww1Sprm::ReCalc() +{ + BOOL bRet = TRUE; + delete pArr; + pArr = NULL; + count = 0; + if (nCountBytes != 255) // not unused? + { + USHORT cbsik = nCountBytes; + BYTE* psik = p; + while (cbsik > 0) + { + USHORT iLen = GetSizeBrutto(psik); + DBG_ASSERT(iLen<=cbsik, "Ww1Sprm"); + if (iLen > cbsik) + cbsik = 0; // ignore the rest: we are wrong... + else + { + psik += iLen; + cbsik = cbsik - iLen; + count++; + } + } + if (bRet + && (pArr = new USHORT[count]) != NULL) + { + cbsik = nCountBytes; + USHORT offset = 0; + USHORT current = 0; + psik = p; + while (current<count) + { + pArr[current++] = offset; + USHORT iLen = GetSizeBrutto(psik); + psik += iLen; + if (iLen > cbsik) + cbsik = 0; + else + cbsik = cbsik - iLen; + offset = offset + iLen; + } + + } + else + count = 0; + } + return bRet; +} + +void Ww1Sprm::DeinitTab() +{ + for (size_t i=0; i < sizeof(aTab)/sizeof(*aTab); ++i) + delete aTab[i]; + memset(aTab, 0, sizeof(aTab)/sizeof(*aTab)); + delete pSingleSprm; +} + +void Ww1Sprm::InitTab() +{ + memset(aTab, 0, sizeof(aTab)/sizeof(*aTab)); + pSingleSprm = new Ww1SingleSprm( 0, DUMPNAME(pUnknown)); + + aTab[ 2] = new Ww1SingleSprmByte(DUMPNAME("sprmPStc")); // 2 pap.istd (style code) + aTab[ 3] = new Ww1SingleSprmByteSized(0, DUMPNAME("sprmPIstdPermute")); // 3 pap.istd permutation + aTab[ 4] = new Ww1SingleSprmByte(DUMPNAME("sprmPIncLevel")); // 4 pap.istddifference + aTab[ 5] = new Ww1SingleSprmPJc(DUMPNAME("sprmPJc")); // 5 pap.jc (justification) + aTab[ 6] = new Ww1SingleSprmBool(DUMPNAME("sprmPFSideBySide")); // 6 pap.fSideBySide + aTab[ 7] = new Ww1SingleSprmPFKeep(DUMPNAME("sprmPFKeep")); // 7 pap.fKeep + aTab[ 8] = new Ww1SingleSprmPFKeepFollow(DUMPNAME("sprmPFKeepFollow")); // 8 pap.fKeepFollow + aTab[ 9] = new Ww1SingleSprmPPageBreakBefore(DUMPNAME("sprmPPageBreakBefore")); // 9 pap.fPageBreakBefore + aTab[ 10] = new Ww1SingleSprmByte(DUMPNAME("sprmPBrcl")); // 10 pap.brcl + aTab[ 11] = new Ww1SingleSprmByte(DUMPNAME("sprmPBrcp")); // 11 pap.brcp + aTab[ 12] = new Ww1SingleSprmByteSized(0, DUMPNAME("sprmPAnld")); // 12 pap.anld (ANLD structure) + aTab[ 13] = new Ww1SingleSprmByte(DUMPNAME("sprmPNLvlAnm")); // 13 pap.nLvlAnm nn + aTab[ 14] = new Ww1SingleSprmBool(DUMPNAME("sprmPFNoLineNumb")); // 14 ap.fNoLnn + aTab[ 15] = new Ww1SingleSprmPChgTabsPapx(DUMPNAME("sprmPChgTabsPapx")); // 15 pap.itbdMac, ... + aTab[ 16] = new Ww1SingleSprmPDxaRight(DUMPNAME("sprmPDxaRight")); // 16 pap.dxaRight + aTab[ 17] = new Ww1SingleSprmPDxaLeft(DUMPNAME("sprmPDxaLeft")); // 17 pap.dxaLeft + aTab[ 18] = new Ww1SingleSprmWord(DUMPNAME("sprmPNest")); // 18 pap.dxaNest + aTab[ 19] = new Ww1SingleSprmPDxaLeft1(DUMPNAME("sprmPDxaLeft1")); // 19 pap.dxaLeft1 + aTab[ 20] = new Ww1SingleSprmPDyaLine(DUMPNAME("sprmPDyaLine")); // 20 pap.lspd an LSPD + aTab[ 21] = new Ww1SingleSprmPDyaBefore(DUMPNAME("sprmPDyaBefore")); // 21 pap.dyaBefore + aTab[ 22] = new Ww1SingleSprmPDyaAfter(DUMPNAME("sprmPDyaAfter")); // 22 pap.dyaAfter + aTab[ 23] = new Ww1SingleSprmTab(0, DUMPNAME(pUnknown)); // 23 pap.itbdMac, pap.rgdxaTab + aTab[ 24] = new Ww1SingleSprmPFInTable(DUMPNAME("sprmPFInTable")); // 24 pap.fInTable + aTab[ 25] = new Ww1SingleSprmPTtp(DUMPNAME("sprmPTtp")); // 25 pap.fTtp + aTab[ 26] = new Ww1SingleSprmPDxaAbs(DUMPNAME("sprmPDxaAbs")); // 26 pap.dxaAbs + aTab[ 27] = new Ww1SingleSprmPDyaAbs(DUMPNAME("sprmPDyaAbs")); // 27 pap.dyaAbs + aTab[ 28] = new Ww1SingleSprmPDxaWidth(DUMPNAME("sprmPDxaWidth")); // 28 pap.dxaWidth + aTab[ 29] = new Ww1SingleSprmPpc(DUMPNAME("sprmPPc")); // 29 pap.pcHorz, pap.pcVert + aTab[ 30] = new Ww1SingleSprmPBrc10(BRC_TOP, DUMPNAME("sprmPBrcTop10")); // 30 pap.brcTop BRC10 + aTab[ 31] = new Ww1SingleSprmPBrc10(BRC_LEFT, DUMPNAME("sprmPBrcLeft10")); // 31 pap.brcLeft BRC10 + aTab[ 32] = new Ww1SingleSprmPBrc10(BRC_BOTTOM, DUMPNAME("sprmPBrcBottom10")); // 32 pap.brcBottom BRC10 + aTab[ 33] = new Ww1SingleSprmPBrc10(BRC_RIGHT, DUMPNAME("sprmPBrcRight10")); // 33 pap.brcRight BRC10 + aTab[ 34] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcBetween10")); // 34 pap.brcBetween BRC10 + aTab[ 35] = new Ww1SingleSprmPBrc10(BRC_LEFT, DUMPNAME("sprmPBrcBar10")); // 35 pap.brcBar BRC10 + aTab[ 36] = new Ww1SingleSprmPFromText(DUMPNAME("sprmPFromText10")); // 36 pap.dxaFromText dxa + aTab[ 37] = new Ww1SingleSprmByte(DUMPNAME("sprmPWr")); // 37 pap.wr wr + aTab[ 38] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcTop")); // 38 pap.brcTop BRC + aTab[ 39] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcLeft")); // 39 pap.brcLeft BRC + aTab[ 40] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcBottom")); // 40 pap.brcBottom BRC + aTab[ 41] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcRight")); // 41 pap.brcRight BRC + aTab[ 42] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcBetween")); // 42 pap.brcBetween BRC + aTab[ 43] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcBar")); // 43 pap.brcBar BRC word + aTab[ 44] = new Ww1SingleSprmBool(DUMPNAME("sprmPFNoAutoHyph")); // 44 pap.fNoAutoHyph + aTab[ 45] = new Ww1SingleSprmWord(DUMPNAME("sprmPWHeightAbs")); // 45 pap.wHeightAbs w + aTab[ 46] = new Ww1SingleSprmWord(DUMPNAME("sprmPDcs")); // 46 pap.dcs DCS + aTab[ 47] = new Ww1SingleSprmWord(DUMPNAME("sprmPShd")); // 47 pap.shd SHD + aTab[ 48] = new Ww1SingleSprmWord(DUMPNAME("sprmPDyaFromText")); // 48 pap.dyaFromText dya + aTab[ 49] = new Ww1SingleSprmWord(DUMPNAME("sprmPDxaFromText")); // 49 pap.dxaFromText dxa + aTab[ 50] = new Ww1SingleSprmBool(DUMPNAME("sprmPFLocked")); // 50 pap.fLocked 0 or 1 byte + aTab[ 51] = new Ww1SingleSprmBool(DUMPNAME("sprmPFWidowControl")); // 51 pap.fWidowControl 0 or 1 byte + + aTab[ 57] = new Ww1SingleSprmByteSized(0, DUMPNAME("sprmCDefault")); // 57 whole CHP (see below) none variable length + aTab[ 58] = new Ww1SingleSprm(0, DUMPNAME("sprmCPlain")); // 58 whole CHP (see below) none 0 + + aTab[ 60] = new Ww1SingleSprm4State(DUMPNAME("sprmCFBold")); // 60 chp.fBold 0,1, 128, or 129 (see below) byte + aTab[ 61] = new Ww1SingleSprm4State(DUMPNAME("sprmCFItalic")); // 61 chp.fItalic 0,1, 128, or 129 (see below) byte + aTab[ 62] = new Ww1SingleSprm4State(DUMPNAME("sprmCFStrike")); // 62 chp.fStrike 0,1, 128, or 129 (see below) byte + aTab[ 63] = new Ww1SingleSprm4State(DUMPNAME("sprmCFOutline")); // 63 chp.fOutline 0,1, 128, or 129 (see below) byte + aTab[ 64] = new Ww1SingleSprm4State(DUMPNAME("sprmCFShadow")); // 64 chp.fShadow 0,1, 128, or 129 (see below) byte + aTab[ 65] = new Ww1SingleSprm4State(DUMPNAME("sprmCFSmallCaps")); // 65 chp.fSmallCaps 0,1, 128, or 129 (see below) byte + aTab[ 66] = new Ww1SingleSprm4State(DUMPNAME("sprmCFCaps")); // 66 chp.fCaps 0,1, 128, or 129 (see below) byte + aTab[ 67] = new Ww1SingleSprm4State(DUMPNAME("sprmCFVanish")); // 67 chp.fVanish 0,1, 128, or 129 (see below) byte + aTab[ 68] = new Ww1SingleSprmWord(DUMPNAME("sprmCFtc")); // 68 chp.ftc ftc word + aTab[ 69] = new Ww1SingleSprmByte(DUMPNAME("sprmCKul")); // 69 chp.kul kul byte + aTab[ 70] = new Ww1SingleSprm(3, DUMPNAME("sprmCSizePos")); // 70 chp.hps, chp.hpsPos (see below) 3 bytes + aTab[ 71] = new Ww1SingleSprmWord(DUMPNAME("sprmCDxaSpace")); // 71 chp.dxaSpace dxa word + aTab[ 72] = new Ww1SingleSprmWord(DUMPNAME("//")); // 72 // + aTab[ 73] = new Ww1SingleSprmByte(DUMPNAME("sprmCIco")); // 73 chp.ico ico byte + aTab[ 74] = new Ww1SingleSprmByte(DUMPNAME("sprmCHps")); // 74 chp.hps hps !byte! + aTab[ 75] = new Ww1SingleSprmByte(DUMPNAME("sprmCHpsInc")); // 75 chp.hps (see below) byte + aTab[ 76] = new Ww1SingleSprmWord(DUMPNAME("sprmCHpsPos")); // 76 chp.hpsPos hps !word! + aTab[ 77] = new Ww1SingleSprmByte(DUMPNAME("sprmCHpsPosAdj")); // 77 chp.hpsPos hps (see below) byte + aTab[ 78] = new Ww1SingleSprmByteSized(0, DUMPNAME(pUnknown)); // 78 ?chp.fBold, chp.fItalic, chp.fSmallCaps, ... + + aTab[ 94] = new Ww1SingleSprmByte(DUMPNAME("sprmPicBrcl")); // 94 pic.brcl brcl (see PIC structure definition) byte + aTab[ 95] = new Ww1SingleSprmByteSized(0, DUMPNAME("sprmPicScale")); // 95 pic.mx, pic.my, pic.dxaCropleft, + + aTab[117] = new Ww1SingleSprmByte(DUMPNAME("sprmSBkc")); // 117 sep.bkc bkc byte + aTab[118] = new Ww1SingleSprmBool(DUMPNAME("sprmSFTitlePage")); // 118 sep.fTitlePage 0 or 1 byte + aTab[119] = new Ww1SingleSprmSColumns(DUMPNAME("sprmSCcolumns")); // 119 sep.ccolM1 # of cols - 1 word + aTab[120] = new Ww1SingleSprmWord(DUMPNAME("sprmSDxaColumns")); // 120 sep.dxaColumns dxa word + + aTab[122] = new Ww1SingleSprmByte(DUMPNAME("sprmSNfcPgn")); // 122 sep.nfcPgn nfc byte + + aTab[125] = new Ww1SingleSprmBool(DUMPNAME("sprmSFPgnRestart")); // 125 sep.fPgnRestart 0 or 1 byte + aTab[126] = new Ww1SingleSprmBool(DUMPNAME("sprmSFEndnote")); // 126 sep.fEndnote 0 or 1 byte + aTab[127] = new Ww1SingleSprmByte(DUMPNAME("sprmSLnc")); // 127 sep.lnc lnc byte + aTab[128] = new Ww1SingleSprmSGprfIhdt(DUMPNAME("sprmSGprfIhdt")); // 128 sep.grpfIhdt grpfihdt (see Headers and Footers topic) byte + aTab[129] = new Ww1SingleSprmWord(DUMPNAME("sprmSNLnnMod")); // 129 sep.nLnnMod non-neg int. word + aTab[130] = new Ww1SingleSprmWord(DUMPNAME("sprmSDxaLnn")); // 130 sep.dxaLnn dxa word + aTab[131] = new Ww1SingleSprmWord(DUMPNAME("sprmSDyaHdrTop")); // 131 sep.dyaHdrTop dya word + aTab[132] = new Ww1SingleSprmWord(DUMPNAME("sprmSDyaHdrBottom")); // 132 sep.dyaHdrBottom dya word + aTab[133] = new Ww1SingleSprmBool(DUMPNAME("sprmSLBetween")); // 133 sep.fLBetween 0 or 1 byte + aTab[134] = new Ww1SingleSprmByte(DUMPNAME("sprmSVjc")); // 134 sep.vjc vjc byte + aTab[135] = new Ww1SingleSprmWord(DUMPNAME("sprmSLnnMin")); // 135 sep.lnnMin lnn word + aTab[136] = new Ww1SingleSprmWord(DUMPNAME("sprmSPgnStart")); // 136 sep.pgnStart pgn word + + aTab[146] = new Ww1SingleSprmWord(DUMPNAME("sprmTJc")); // 146 tap.jc jc word (low order byte is significant) + aTab[147] = new Ww1SingleSprmWord(DUMPNAME("sprmTDxaLeft")); // 147 tap.rgdxaCenter (see below) dxa word + aTab[148] = new Ww1SingleSprmWord(DUMPNAME("sprmTDxaGapHalf")); // 148 tap.dxaGapHalf, tap.rgdxaCenter (see below) dxa word + + aTab[152] = new Ww1SingleSprmTDefTable10(DUMPNAME("sprmTDefTable10")); // 152 tap.rgdxaCenter, tap.rgtc complex (see below) variable length + aTab[153] = new Ww1SingleSprmWord(DUMPNAME("sprmTDyaRowHeight")); // 153 tap.dyaRowHeight dya word + + aTab[158] = new Ww1SingleSprm(4, DUMPNAME("sprmTInsert")); // 158 tap.rgdxaCenter,tap.rgtc complex (see below) 4 bytes + aTab[159] = new Ww1SingleSprmWord(DUMPNAME("sprmTDelete")); // 159 tap.rgdxaCenter, tap.rgtc complex (see below) word + aTab[160] = new Ww1SingleSprm(4, DUMPNAME("sprmTDxaCol")); // 160 tap.rgdxaCenter complex (see below) 4 bytes + aTab[161] = new Ww1SingleSprmWord(DUMPNAME("sprmTMerge")); // 161 tap.fFirstMerged, tap.fMerged complex (see below) word + aTab[162] = new Ww1SingleSprmWord(DUMPNAME("sprmTSplit")); // 162 tap.fFirstMerged, tap.fMerged complex (see below) word + aTab[163] = new Ww1SingleSprm(5, DUMPNAME("sprmTSetBrc10")); // 163 tap.rgtc[].rgbrc complex (see below) 5 bytes +} + +////////////////////////////////////////////////////////////// SprmPapx +Ww1SprmPapx::Ww1SprmPapx(BYTE* pByte, USHORT nSize) : + Ww1Sprm(Sprm(pByte, nSize), SprmSize(pByte, nSize)) +{ + memset(&aPapx, 0, sizeof(aPapx)); + memcpy(&aPapx, pByte, nSize<sizeof(aPapx)?nSize:sizeof(aPapx)); +} + +USHORT Ww1SprmPapx::SprmSize(BYTE*, USHORT nSize) +{ + USHORT nRet = 0; + if (nSize >= sizeof(W1_PAPX)) + nRet = nSize - ( sizeof(W1_PAPX) - 1 ); // im W1_PAPX ist das + // 1. SprmByte enthalten + return nRet; +} + +BYTE* Ww1SprmPapx::Sprm(BYTE* pByte, USHORT nSize) +{ + BYTE* pRet = NULL; + if (nSize >= sizeof(W1_PAPX)) + pRet = ((W1_PAPX*)(pByte))->grpprlGet(); + return pRet; +} + +/////////////////////////////////////////////////////////////////// Plc +Ww1Plc::Ww1Plc(Ww1Fib& rInFib, ULONG ulFilePos, USHORT nInCountBytes, + USHORT nInItemSize) + : p(0), nCountBytes(nInCountBytes), iMac(0), nItemSize(nInItemSize), + bOK(false), rFib(rInFib) +{ + if (!nCountBytes) + bOK = true; + else + { + if (rFib.GetStream().Seek(ulFilePos) == (ULONG)ulFilePos) + { + if ((p = new BYTE[nCountBytes]) != NULL) + { + if (rFib.GetStream().Read(p, nCountBytes) == (ULONG)nCountBytes) + { + bOK = true; + iMac = (nCountBytes - + sizeof(SVBT32)) / (sizeof(SVBT32) + nItemSize); + DBG_ASSERT(iMac * ((USHORT)sizeof(ULONG) + nItemSize) + + (USHORT)sizeof(SVBT32) == nCountBytes, "Ww1Plc"); + } + } + } + } +} + +Ww1Plc::~Ww1Plc() +{ + delete p; +} + +void Ww1Plc::Seek(ULONG ulSeek, USHORT& nIndex) +{ + if (iMac) + for (;nIndex <= iMac && Where(nIndex) < ulSeek;nIndex++) + ; +} + +ULONG Ww1Plc::Where(USHORT nIndex) +{ + ULONG ulRet = 0xffffffff; + DBG_ASSERT(nIndex <= iMac, "index out of bounds"); + if (iMac && nIndex <= iMac) + ulRet = SVBT32ToUInt32(p + sizeof(SVBT32) * nIndex); + return ulRet; +} + +BYTE* Ww1Plc::GetData(USHORT nIndex) +{ + BYTE* pRet = NULL; + DBG_ASSERT(nIndex < iMac, "index out of bounds"); + if (nIndex < iMac) + pRet = p + (iMac + 1) * sizeof(SVBT32) + + nIndex * nItemSize; // Pointer auf Inhalts-Array + return pRet; +} + +/////////////////////////////////////////////////////////////////// Sep + +//////////////////////////////////////////////////////////////// PlcSep + +//////////////////////////////////////////////////////////////// PlcPap + +//////////////////////////////////////////////////////////////// PlcChp + +//////////////////////////////////////////////////////////////// PlcFnr + +///////////////////////////////////////////////////////////// PlcFnText + +///////////////////////////////////////////////////////////// PlcFields + +///////////////////////////////////////////////////////////// PlcBookmarks +// class Ww1StringList liest im Ctor eine Anzahl von P-Strings aus dem Stream +// in den Speicher und patcht sie zu C-Strings um. +// Die Anzahl wird in nMax zurueckgeliefert. +// im Index 0 stehen alle Strings nacheinander, ab Index 1 werden +// die einzelnen Strings referenziert. +Ww1StringList::Ww1StringList( SvStream& rSt, ULONG nFc, USHORT nCb ) + : pIdxA(0), nMax(0) +{ + if( nCb > 2 ) // ueberhaupt Eintraege ? + { + SVBT16 nCountBytes; + DBG_ASSERT(nCb > sizeof(nCountBytes), "Ww1StringList"); + if (rSt.Seek(nFc) == (ULONG)nFc) + if (rSt.Read(nCountBytes, sizeof(nCountBytes)) + == sizeof(nCountBytes)) // Laenge steht hier nochmal + { + DBG_ASSERT(SVBT16ToShort(nCountBytes) + == nCb, "redundant-size missmatch"); + // hoffentlich sind sie immer gleich + sal_Char* pA = new sal_Char[nCb - sizeof(nCountBytes) + 1]; + // Alloziere PString-Array + //~ Ww1: new-NULL + if (rSt.Read(pA, nCb - sizeof(nCountBytes)) + == (ULONG)nCb - sizeof(nCountBytes)) // lese alle + {}// do nothing + // Zaehle, wieviele Fonts enthalten + long nLeft = nCb - sizeof(nCountBytes); + sal_Char* p = pA; + while (1) + { + USHORT nNextSiz; + nNextSiz = *p + 1; + if(nNextSiz > nLeft) + break; + nMax++; + nLeft -= nNextSiz; + if(nLeft < 1) // naechste Laenge muss gelesen werden koennen + break; + p = p + nNextSiz; + } + if (nMax) + { + pIdxA = new sal_Char*[nMax+1]; // alloziere Index-Array + pIdxA[0] = pA; // Index 0 : alles + // ab Index 1 C-Strings + pIdxA[1] = pA + 1; // fuelle Index-Array + USHORT i = 2; + p = pA; + BYTE nL = *p; + while(1) + { + p += nL + 1; // Neues Laengen-Byte + nL = *p; // merke Laenge + *p = '\0'; // mach C-String draus + if( i > nMax ) + break; + pIdxA[i] = p + 1; // Ptr auf C-String + i++; + } + } + else + pIdxA = 0; // Keine Eintraege -> kein Array + } + } +} +const String Ww1StringList::GetStr( USHORT nNum ) const +{ + String sRet; + if( nNum <= nMax ) + sRet = String( pIdxA[ nNum+1 ], RTL_TEXTENCODING_MS_1252 ); + return sRet; +} + +Ww1Bookmarks::Ww1Bookmarks(Ww1Fib& rInFib) + : aNames(rInFib), rFib(rInFib), nIsEnd(0) +{ + pPos[0] = new Ww1PlcBookmarkPos(rFib, rFib.GetFIB().fcPlcfbkfGet(), + rFib.GetFIB().cbPlcfbkfGet(), FALSE); + nPlcIdx[0] = 0; + pPos[1] = new Ww1PlcBookmarkPos(rFib, rFib.GetFIB().fcPlcfbklGet(), + rFib.GetFIB().cbPlcfbklGet(), TRUE); + nPlcIdx[1] = 0; + bOK = !aNames.GetError() && !pPos[0]->GetError() && !pPos[1]->GetError(); +} + +// Der Operator ++ hat eine Tuecke: Wenn 2 Bookmarks aneinandergrenzen, dann +// sollte erst das Ende des ersten und dann der Anfang des 2. erreicht werden. +// Liegen jedoch 2 Bookmarks der Laenge 0 aufeinander, *muss* von jedem Bookmark +// erst der Anfang und dann das Ende gefunden werden. +// Der Fall: ][ +// [...] +// ][ +// ist noch nicht geloest, dabei muesste ich in den Anfangs- und Endindices +// vor- und zurueckspringen, wobei ein weiterer Index oder ein Bitfeld +// oder etwas aehnliches zum Merken der bereits abgearbeiteten Bookmarks +// noetig wird. +void Ww1Bookmarks::operator ++( int ) +{ + if( bOK ) + { + nPlcIdx[nIsEnd]++; + + ULONG l0 = pPos[0]->Where(nPlcIdx[0]); + ULONG l1 = pPos[1]->Where(nPlcIdx[1]); + if( l0 < l1 ) + nIsEnd = 0; + else if( l1 < l0 ) + nIsEnd = 1; + else + nIsEnd = ( nIsEnd ) ? 0 : 1; + } +} + +long Ww1Bookmarks::GetHandle() const +{ + if( bOK ) + { + if( nIsEnd ) + return nPlcIdx[1]; + + const BYTE* p = pPos[0]->GetData( nPlcIdx[0] ); + if( p ) + return SVBT16ToShort( p ); + } + return LONG_MAX; +} + +long Ww1Bookmarks::Len() const +{ + if( nIsEnd ) + { + DBG_ASSERT( FALSE, "Falscher Aufruf (1) von Ww1Bookmarks::Len()" ); + return 0; + } + USHORT nEndIdx = SVBT16ToShort(pPos[0]->GetData(nPlcIdx[0])); + return pPos[1]->Where(nEndIdx) - pPos[0]->Where(nPlcIdx[0]); +} + +const String Ww1Bookmarks::GetName() const +{ + if( nIsEnd ) + return String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "???" )); + return aNames.GetStr( nPlcIdx[0] ); +} + +/////////////////////////////////////////////////////////////////// Fkp +Ww1Fkp::Ww1Fkp(SvStream& rStream, ULONG ulFilePos, USHORT _nItemSize) : + nItemSize(_nItemSize), + bOK(FALSE) +{ + if (rStream.Seek(ulFilePos) == (ULONG)ulFilePos) + if (rStream.Read(aFkp, sizeof(aFkp)) == sizeof(aFkp)) + bOK = TRUE; +} + +ULONG Ww1Fkp::Where(USHORT nIndex) +{ + ULONG lRet = 0xffffffff; + DBG_ASSERT(nIndex<=Count(), "index out of bounds"); + if (nIndex<=Count()) + lRet = SVBT32ToUInt32(aFkp+nIndex*sizeof(SVBT32)); + return lRet; +} + +BYTE* Ww1Fkp::GetData(USHORT nIndex) +{ + BYTE* pRet = NULL; + DBG_ASSERT(nIndex<=Count(), "index out of bounds"); + if (nIndex<=Count()) + pRet = aFkp + (Count()+1) * sizeof(SVBT32) + + nIndex * nItemSize; // beginn der strukturen + return pRet; +} + +//////////////////////////////////////////////////////////////// FkpPap +BOOL Ww1FkpPap::Fill(USHORT nIndex, BYTE*& p, USHORT& rnCountBytes) +{ + DBG_ASSERT( nIndex < Count(), "Ww1FkpPap::Fill() Index out of Range" ); + USHORT nOffset = SVBT8ToByte(GetData(nIndex)) * 2; + if (nOffset) + { + DBG_ASSERT(nOffset>(USHORT)(Count()*sizeof(SVBT32)), "calc error"); + rnCountBytes = SVBT8ToByte(aFkp+nOffset) * 2; + nOffset += sizeof(SVBT8); + if( nOffset + rnCountBytes < 511 ) // SH: Assert schlug 1 zu frueh zu + rnCountBytes++; // SH: Ich weiss nicht genau, + // ob das letzte Byte des PAPX + // genutzt wird, aber so vergessen + // wir keins und sind trotzdem + // auf der sicheren Seite + DBG_ASSERT(nOffset+rnCountBytes <= 511, "calc error"); + p = aFkp + nOffset; + } + else + { + p = NULL; + rnCountBytes = 0; + } + return TRUE; +} + +//////////////////////////////////////////////////////////////// FkpChp +BOOL Ww1FkpChp::Fill(USHORT nIndex, W1_CHP& aChp) +{ + DBG_ASSERT( nIndex < Count(), "Ww1FkpChp::Fill() Index out of Range" ); + memset(&aChp, 0, sizeof(aChp)); // Default, da verkuerzt gespeichert + USHORT nOffset = GetData(nIndex)[0] * 2; + if (nOffset) + { + DBG_ASSERT(nOffset>(USHORT)(Count()*sizeof(SVBT32)), "calc error"); + USHORT nCountBytes = aFkp[nOffset]; + nOffset += sizeof(SVBT8); + DBG_ASSERT(nCountBytes <= 511-nOffset, "calc error"); + DBG_ASSERT(nCountBytes <= sizeof(aChp), "calc error"); + memcpy(&aChp, aFkp+nOffset, nCountBytes); + } + return TRUE; +} + +///////////////////////////////////////////////////////////////// Assoc +Ww1Assoc::Ww1Assoc(Ww1Fib& _rFib) + : rFib(_rFib), pBuffer(NULL), bOK(FALSE) +{ + USHORT cb = rFib.GetFIB().cbSttbfAssocGet(); + USHORT i; + + for ( i = 0; i < MaxFields; i++ ) + pStrTbl[i] = NULL; + if ((pBuffer = new sal_Char[cb]) != NULL + && rFib.GetStream().Seek(rFib.GetFIB().fcSttbfAssocGet()) == + rFib.GetFIB().fcSttbfAssocGet() + && rFib.GetStream().Read(pBuffer, cb) == cb) + { + USHORT j; + DBG_ASSERT( cb == SVBT16ToShort( *(SVBT16*)pBuffer ), "size missmatch"); + for (i=0,j=sizeof(SVBT16);j<cb && i<Criteria1;i++) + { + pStrTbl[i] = pBuffer+j; + j += (*pBuffer + j) + 1; + } + bOK = TRUE; + } +} + +String Ww1Assoc::GetStr(USHORT code) +{ + String sRet; + DBG_ASSERT(code<MaxFields, "out of range"); + if (pStrTbl[code] != NULL) + for( USHORT i=0;i<pStrTbl[code][0];i++ ) + sRet += String( pStrTbl[code][i+1], RTL_TEXTENCODING_MS_1252 ); + return sRet; +} + +/////////////////////////////////////////////////////////////////// Pap +Ww1Pap::Ww1Pap(Ww1Fib& _rFib) + : Ww1PlcPap(_rFib), nPlcIndex(0), nPushedPlcIndex(0xffff), nFkpIndex(0), + nPushedFkpIndex(0xffff), ulOffset(0), pPap(0) +{ +} + +void Ww1Pap::Seek(ULONG ulSeek) +{ + while (ulSeek > Where()) + (*this)++; +} + +// SH: Where hat einen Parameter mitbekommen, der sagt, ob bei Neuanlegen eines +// Fkps der zugehoerige Index auf 0 gesetzt werden soll +// ( darf fuer Push/Pop nicht passieren ) +// Ein eleganterer Weg faellt mir auf die Schnelle nicht ein +ULONG Ww1Pap::Where( BOOL bSetIndex ) +{ + ULONG ulRet = 0xffffffff; + if (pPap == NULL) + if (nPlcIndex < Count()) + { + pPap = new Ww1FkpPap(rFib.GetStream(), + SVBT16ToShort(GetData(nPlcIndex)) << 9); + if( bSetIndex ) + nFkpIndex = 0; + } + if (pPap != NULL) + if (nFkpIndex <= pPap->Count()) + ulRet = pPap->Where(nFkpIndex) - rFib.GetFIB().fcMinGet(); + return ulRet; +} + +void Ww1Pap::operator++(int) +{ + if (pPap != NULL) + if (++nFkpIndex > pPap->Count()) + { + delete pPap; + pPap = NULL; + nPlcIndex++; + } +} + +// SH: FindSprm sucht in grpprl nach Sprm nId +// Rueckgabe: Pointer oder 0 +BOOL Ww1Pap::FindSprm(USHORT nId, BYTE* pStart, BYTE* pEnd) +{ + Ww1Sprm aSprm( pStart, static_cast< USHORT >(pEnd-pStart) ); + USHORT nC = aSprm.Count(); + USHORT i; + BYTE nI; + USHORT nLen; + BYTE *pData; + for( i = 0; i < nC; i++ ){ + aSprm.Fill( i, nI, nLen, pData ); + if( nI == nId ) + return TRUE; + } + return FALSE; +} + +BOOL Ww1Pap::HasId0(USHORT nId) +{ + BOOL bRet = FALSE; + UpdateIdx(); + + if( !pPap ){ + DBG_ASSERT( FALSE, "Ww1Pap::HasId():: kann kein pPap erzeugen" ); + return FALSE; + } + + BYTE* pByte; + USHORT n; + if( pPap->Fill(nFkpIndex, pByte, n) ){ + BYTE* p2 = ((W1_PAPX*)(pByte))->grpprlGet(); // SH: Offset fehlte + bRet = FindSprm( nId, p2, pByte + n ); + } + return bRet; +} + +BOOL Ww1Pap::HasId(USHORT nId) +{ + BOOL bRet = FALSE; + USHORT nPushedPlcIndex2 = nPlcIndex; + USHORT nPushedFkpIndex2 = nFkpIndex; + bRet = HasId0( nId ); + if (nPlcIndex != nPushedPlcIndex2) + { + delete pPap; + pPap = NULL; + } + nPlcIndex = nPushedPlcIndex2; + nFkpIndex = nPushedFkpIndex2; + Where( FALSE ); + return bRet; +} + +/////////////////////////////////////////////////////////////////// Chp +Ww1Chp::Ww1Chp(Ww1Fib& _rFib) + : Ww1PlcChp(_rFib), nPlcIndex(0), nPushedPlcIndex(0xffff), nFkpIndex(0), + nPushedFkpIndex(0xffff), ulOffset(0), pChp(0) +{ +} + +void Ww1Chp::Seek(ULONG ulSeek) +{ + while (ulSeek > Where()) + (*this)++; +} + +// SH: Where hat einen Parameter mitbekommen, der sagt, ob bei Neuanlegen eines +// Fkps der zugehoerige Index auf 0 gesetzt werden soll +// ( darf fuer Push/Pop nicht passieren ) +// Ein eleganterer Weg faellt mir auf die Schnelle nicht ein +ULONG Ww1Chp::Where( BOOL bSetIndex ) +{ + ULONG ulRet = 0xffffffff; + if (pChp == NULL) + if (nPlcIndex < Count()) + { + pChp = new Ww1FkpChp(rFib.GetStream(), + SVBT16ToShort(GetData(nPlcIndex)) << 9); + if( bSetIndex ) + nFkpIndex = 0; + } + if (pChp != NULL) + if (nFkpIndex <= pChp->Count()) + ulRet = pChp->Where(nFkpIndex) - + rFib.GetFIB().fcMinGet() - ulOffset; + return ulRet; +} + +void Ww1Chp::operator++(int) +{ + if (pChp != NULL) + if (++nFkpIndex > pChp->Count()) + { + delete pChp; + pChp = NULL; + nPlcIndex++; + } +} + +////////////////////////////////////////////////////////////// Manager +Ww1Manager::Ww1Manager(SvStream& rStrm, ULONG nFieldFlgs) + : bOK(FALSE), bInTtp(FALSE), bInStyle(FALSE), bStopAll(FALSE), aFib(rStrm), + aDop(aFib), aFonts(aFib, nFieldFlgs), aDoc(aFib), pDoc(&aDoc), + ulDocSeek(0), pSeek(&ulDocSeek), aFld(aFib), pFld(&aFld), aChp(aFib), + aPap(aFib), aFtn(aFib), aBooks(aFib), + aSep(aFib, aDop.GetDOP().grpfIhdtGet()) +{ + bOK = !aFib.GetError() + && !aFib.GetFIB().fComplexGet() + && !aDoc.GetError() + && !aSep.GetError() + && !aPap.GetError() + && !aChp.GetError() + && !aFld.GetError() + && !aFtn.GetError() + && !aBooks.GetError(); +} + +BOOL Ww1Manager::HasInTable() +{ + return aPap.HasId(24); // Ww1SingleSprmPFInTable +} + +BOOL Ww1Manager::HasTtp() +{ + return aPap.HasId(25); // Ww1SingleSprmPTtp +} + +BOOL Ww1Manager::HasPPc() +{ + return aPap.HasId(29); // Ww1SingleSprmPPc +} + +BOOL Ww1Manager::HasPDxaAbs() +{ + return aPap.HasId(26); // Ww1SingleSprmPDxaAbs +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww1/w1class.hxx b/sw/source/filter/ww1/w1class.hxx new file mode 100644 index 000000000000..49547f65b892 --- /dev/null +++ b/sw/source/filter/ww1/w1class.hxx @@ -0,0 +1,1599 @@ +/* -*- 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. + * + ************************************************************************/ +#include <tools/string.hxx> +#include <tools/debug.hxx> + +// local +#include <w1struct.hxx> + +#ifdef DUMP +#include <fstream.h> +#endif + +#include <ostream> + +using std::ostream; + +class SvxFontItem; +class SvxBorderLine; +class SvxBoxItem; +class SvStream; +class SwField; +class Ww1Annotation; +class Ww1AtnText; +class Ww1Chp; +class Ww1DocText; +class Ww1Dop; +class Ww1Fib; +class Ww1Fkp; +class Ww1FkpChp; +class Ww1FkpPap; +class Ww1Fonts; +class Ww1Manager; +class Ww1McrText; +class Ww1Pap; +class Ww1PlainText; +class Ww1Plc; +class Ww1PlcAnnotationRef; +class Ww1PlcAnnotationTxt; +class Ww1PlcChp; +class Ww1PlcFields; +class Ww1PlcFootnoteRef; +class Ww1PlcFootnoteTxt; +class Ww1PlcGlossary; +class Ww1PlcHdd; +class Ww1PlcPap; +class Ww1PlcSep; +class Ww1Shell; +class Ww1Sprm; +class Ww1SprmPapx; +class Ww1SprmSep; +class Ww1Style; +class Ww1StyleSheet; + +/////////////////////////////////////////////////////////////////////// +// +// nach moeglichkeit wurden in diesem modul methoden aehnlicher +// funktionalitaet gleich benannt. Die namen wurden wenn moeglich vom +// ww-filter uebernommen. +// Where() gibt die position eines elements. dies kann sowohl eine +// seek-position im stream als auch ein relativer offset sein, da dies +// bei word durcheinander geht. die methoden sind durch kommentare +// gekennzeichnet, ob sie sich auf positionen in der datei oder +// innerhalb des textes beziehen. vorsicht: innerhalb des textes kann +// verschiedene texte in der datei bedeuten. +// Count() gibt die anzahl der elemente zurueck. vorsicht bei +// n/n-1-feldern (word speichert strukturen gern in doppel-arrays, in +// denen das erste n elemente, das zweite jedoch n-1 elemente +// enthaelt. +// Fill() fuellt uebergebene referenzen mit daten aus den +// word-strukturen. +// GetData() gibt zeiger auf den datenbereich zurueck +// GetError() gibt zurueck, ob fehler aufgetreten ist +// Start(), Stop(), Out(), op<< siehe modul w1filter +// Dump() siehe modul w1dump +// + +/////////////////////////////////////////////////////////////////// Fib +// +// file information block: wurzel des uebels: steht am beginn der +// datei (seek(0)) und enthaelt alle positionen der strukturen der +// datei +// +class Ww1Fib +{ + W1_FIB aFib; + BOOL bOK; + SvStream& rStream; +public: + Ww1Fib(SvStream&); + friend ostream& operator <<(ostream&, Ww1Fib&); + W1_FIB& GetFIB() { return aFib; } + BOOL GetError() { return !bOK; } + SvStream& GetStream() { return rStream; } +}; + +/////////////////////////////////////////////////////////////////// Dop +// +// document property: eigenschaften des gesamten dokuments +// +class Ww1Dop +{ + W1_DOP aDop; + Ww1Fib& rFib; + BOOL bOK; +public: + Ww1Dop(Ww1Fib&); + BOOL GetError() { + return !bOK; } + W1_DOP& GetDOP() { + return aDop; } + friend ostream& operator <<(ostream&, Ww1Dop&); + void Out(Ww1Shell&); +}; + +///////////////////////////////////////////////////////////// PlainText +// +// ww-dateien koennen mehrere textbloecke enthalten (main-text, +// fusznoten etc). PlainText vereinigt die gemeinsamkeiten +// +class Ww1PlainText +{ +protected: + Ww1Fib& rFib; + ULONG ulFilePos; + ULONG ulCountBytes; + ULONG ulSeek; + BOOL bOK; +public: + Ww1PlainText(Ww1Fib& rWwFib, ULONG nFilePos, ULONG nCountBytes); + // innerhalb des textes + ULONG Where() const { return ulSeek; } + void Seek( ULONG ulNew ) + { + DBG_ASSERT(ulNew < ulCountBytes, "Ww1PlainText"); + if (ulNew < ulCountBytes) + ulSeek = ulNew; + } + + ULONG Count() const { return ulCountBytes; } + void SetCount(ULONG ulNew) + { + ulNew += ulSeek; + if (ulCountBytes > ulNew) + ulCountBytes = ulNew; + } + void operator++(int) + { + DBG_ASSERT(ulSeek+1<ulCountBytes, "Ww1PlainText"); + ulSeek++; + } + BOOL GetError() { return !bOK; } + sal_Unicode Out( Ww1Shell&, ULONG& ); + sal_Unicode Out( String&, ULONG=0xffffffff); + sal_Unicode Out( sal_Unicode& ); + friend ostream& operator <<(ostream&, Ww1PlainText&); + String& Fill( String&, ULONG=0, ULONG=0xffffffff ); + sal_Unicode operator []( ULONG ); + String GetText( ULONG ulOffset, ULONG nLen ) const; + + enum Consts { MinChar = 32 }; + static BOOL IsChar( sal_Unicode c ) { return c >= MinChar; } +}; + +/////////////////////////////////////////////////////////////// DocText +class Ww1DocText : public Ww1PlainText +{ +public: + Ww1DocText(Ww1Fib& rFibL) : + Ww1PlainText(rFibL, rFibL.GetFIB().fcMinGet(), + rFibL.GetFIB().ccpTextGet()) { + } +}; + +/////////////////////////////////////////////////////////////// FtnText +class Ww1FtnText : public Ww1PlainText +{ +public: + ULONG Offset(Ww1Fib& rFibL) { + return rFibL.GetFIB().ccpTextGet(); } + Ww1FtnText(Ww1Fib& rFibL) : + Ww1PlainText(rFibL, rFibL.GetFIB().fcMinGet() + + Offset(rFibL), rFibL.GetFIB().ccpFtnGet()) { + } +}; + +/////////////////////////////////////////////////////////////// HddText +class Ww1HddText : public Ww1PlainText +{ +public: + ULONG Offset(Ww1Fib& rFibL) { + return rFibL.GetFIB().ccpTextGet() + rFibL.GetFIB().ccpFtnGet(); } + Ww1HddText(Ww1Fib& rFibL) : + Ww1PlainText(rFibL, rFibL.GetFIB().fcMinGet() + + Offset(rFibL), rFibL.GetFIB().ccpHddGet()) { + } +}; + +/////////////////////////////////////////////////////////////// McrText +class Ww1McrText : public Ww1PlainText +{ +public: + ULONG Offset(Ww1Fib& rFibL) { + return rFibL.GetFIB().ccpTextGet() + rFibL.GetFIB().ccpFtnGet() + + rFibL.GetFIB().ccpHddGet(); } + Ww1McrText(Ww1Fib& rFibL) : + Ww1PlainText(rFibL, rFibL.GetFIB().fcMinGet() + + Offset(rFibL), rFibL.GetFIB().ccpMcrGet()) { + } +}; + +/////////////////////////////////////////////////////////////// AtnText +class Ww1AtnText : public Ww1PlainText +{ +public: + ULONG Offset(Ww1Fib& rFibL) { + return rFibL.GetFIB().ccpTextGet() + rFibL.GetFIB().ccpFtnGet() + + rFibL.GetFIB().ccpHddGet() + rFibL.GetFIB().ccpMcrGet(); } + Ww1AtnText(Ww1Fib& rFibL) : + Ww1PlainText(rFibL, rFibL.GetFIB().fcMinGet() + + Offset(rFibL), rFibL.GetFIB().ccpAtnGet()) { + } +}; + +///////////////////////////////////////////////////////////////// Style +// +// ein einzelner style oder vorlage +// +class Ww1Style +{ + String aName; + W1_CHP aChpx; + Ww1SprmPapx* pPapx; + Ww1StyleSheet* pParent; + BYTE stcBase; + BYTE stcNext; + BOOL bUsed; +public: + Ww1Style(); + ~Ww1Style(); + BOOL IsUsed() const { return bUsed; } + void SetDefaults(BYTE); + void SetParent(Ww1StyleSheet* newParent) { pParent = newParent; } + void SetName(const String& rName) { bUsed = TRUE; aName = rName; } + const String& GetName() const { return aName; } +// Ww1Style& GetNext(); + Ww1Style& GetBase(); + USHORT GetnBase() const { return stcBase; } + USHORT GetnNext() const { return stcNext; } + USHORT ReadName(BYTE*&, USHORT&, USHORT stc); + USHORT ReadChpx(BYTE*&, USHORT&); + USHORT ReadPapx(BYTE*&, USHORT&); + USHORT ReadEstcp(BYTE*&, USHORT&); + friend ostream& operator <<(ostream&, Ww1Style&); + void Out(Ww1Shell&, Ww1Manager&); +}; + +//////////////////////////////////////////////////////////// StyleSheet +// +// die sammlung aller vorlagen (max. 256) +// +class Ww1StyleSheet +{ + Ww1Style aStyles[256]; + USHORT cstcStd; // count style code standard + Ww1Fib& rFib; + BOOL bOK; + USHORT ReadNames(BYTE*&, USHORT&); + USHORT ReadChpx(BYTE*&, USHORT&); + USHORT ReadPapx(BYTE*&, USHORT&); + USHORT ReadEstcp(BYTE*&, USHORT&); + + void OutDefaults(Ww1Shell& rOut, Ww1Manager& rMan, USHORT stc); + void OutOne(Ww1Shell& rOut, Ww1Manager& rMan, USHORT stc); + void OutOneWithBase(Ww1Shell& rOut, Ww1Manager& rMan, USHORT stc, + BYTE* pbStopRecur ); +public: + Ww1StyleSheet(Ww1Fib& rFib); + Ww1Style& GetStyle(USHORT stc) { + return aStyles[stc]; } + USHORT Count() { + return 256; } + friend ostream& operator <<(ostream&, Ww1StyleSheet&); + void Out(Ww1Shell&, Ww1Manager&); + friend class Ww1Style; + BOOL GetError() { + return !bOK; } +}; + +///////////////////////////////////////////////////////////////// Fonts +// +// ww kennt nur font-nummern beim formatieren. nebenher gibts ein +// array von fonts, damit man aus der nummer einen konkreten font +// machen kann. +// +class Ww1Fonts +{ +protected: + W1_FFN** pFontA; // Array of Pointers to Font Description + Ww1Fib& rFib; + ULONG nFieldFlags; + USHORT nMax; // Array-Groesse + BOOL bOK; +public: + Ww1Fonts(Ww1Fib&, ULONG nFieldFlgs); + ~Ww1Fonts() { + if (pFontA) + DELETEZ(pFontA[0]); + DELETEZ(pFontA); } + W1_FFN* GetFFN(USHORT nNum); + USHORT Count() { + return nMax; } + friend ostream& operator <<(ostream&, Ww1Fonts&); + BOOL GetError() { + return !bOK; } + SvxFontItem GetFont(USHORT); +}; + +//////////////////////////////////////////////////////////// SingleSprm +// +// diese klassen ersetzen die aSprmTab etc des ww6-filters. die +// funktionspointer sind hier virtuale methoden, fuer die typen (byte, +// word, var-sized etc) gibt es abgeleitete klassen. diese haben +// methoden zum bestimmen der groesze, dumpen und shell-ausgeben der +// Sprms. +// die klassen werden mit new (in InitTab()) erzeugt und nach ihrem +// code in die tabelle gestellt. zum aktivieren ruft man nun nur noch +// die entsprechende methode des objektes in der tabelle auf. +// wohlgemerkt: SingleSprms sind die _beschreibung_ und _funktion_ der +// Sprms, nicht deren inhalt. dieser musz uebergeben werden an die +// einzelnen methoden wie Size, Dump und Start/Stop. +// +class Ww1SingleSprm +{ +public: +#ifdef DUMP +// +// allein die virtuellen methoden stehen in der vtab, also je nachdem, +// ob fuer dumper oder filter uebersetzt wird ausblenden: das spart +// platz. ausserdem stehen die methoden fuer dumper bzw filter in +// verschiedenen modulen, die im jeweils anderen projekt nicht +// uebersetzt werden. das diese dann beim linken nicht zur verfuegung +// stehen faellt dann auch nicht auf. Der Namensstring ist nur im +// Dumper noetig: weg damit im Filter. +// + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); + void Stop(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); + virtual ostream& Dump(ostream&, BYTE*, USHORT); + const sal_Char* sName; +#else + virtual void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); + virtual void Stop(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); + ostream& Dump(ostream&, BYTE*, USHORT); +#endif + virtual USHORT Size(BYTE*); + USHORT nCountBytes; + + Ww1SingleSprm(USHORT nBytes, const sal_Char* /*pName*/ = 0 ) + : nCountBytes(nBytes) +#ifdef DUMP + , sName( pName) +#endif + { + } +}; + +class Ww1SingleSprmByteSized : public Ww1SingleSprm { +public: +// ostream& Dump(ostream&, BYTE*, USHORT); + USHORT Size(BYTE*); + Ww1SingleSprmByteSized(USHORT nBytes, sal_Char* sName = 0) : + Ww1SingleSprm(nBytes, sName) { + } +}; + +class Ww1SingleSprmWordSized : public Ww1SingleSprm { +public: +// ostream& Dump(ostream&, BYTE*, USHORT); + USHORT Size(BYTE*); + Ww1SingleSprmWordSized(USHORT nBytes, sal_Char* sName = 0) : + Ww1SingleSprm(nBytes, sName) { + } +}; + +class Ww1SingleSprmByte : public Ww1SingleSprm { +public: + ostream& Dump(ostream&, BYTE*, USHORT); +// USHORT Size(BYTE*); + Ww1SingleSprmByte(sal_Char* sName = 0) : + Ww1SingleSprm(1, sName) { + } +}; + +class Ww1SingleSprmBool : public Ww1SingleSprmByte { +public: + ostream& Dump(ostream&, BYTE*, USHORT); +// USHORT Size(BYTE*); + Ww1SingleSprmBool(sal_Char* sName = 0) : + Ww1SingleSprmByte(sName) { + } +}; + +class Ww1SingleSprm4State : public Ww1SingleSprmByte { +public: + ostream& Dump(ostream&, BYTE*, USHORT); +// USHORT Size(BYTE*); + Ww1SingleSprm4State(sal_Char* sName = 0) : + Ww1SingleSprmByte(sName) { + } +}; + +class Ww1SingleSprmWord : public Ww1SingleSprm { +public: + ostream& Dump(ostream&, BYTE*, USHORT); +// USHORT Size(BYTE*); + Ww1SingleSprmWord(sal_Char* sName = 0) + : Ww1SingleSprm(2, sName) {} +}; + +class Ww1SingleSprmLong : public Ww1SingleSprm { +public: + ostream& Dump(ostream&, BYTE*, USHORT); +// USHORT Size(BYTE*); + Ww1SingleSprmLong(sal_Char* sName = 0) : + Ww1SingleSprm(4, sName) { + } +}; + +class Ww1SingleSprmTab : public Ww1SingleSprm { +public: + ostream& Dump(ostream&, BYTE*, USHORT); + USHORT Size(BYTE*); + Ww1SingleSprmTab(USHORT nBytes, sal_Char* sName = 0) : + Ww1SingleSprm(nBytes, sName) { + } +}; + +class Ww1SingleSprmPJc : public Ww1SingleSprmByte { +public: + Ww1SingleSprmPJc(sal_Char* sName) : + Ww1SingleSprmByte(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); + void Stop(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPDxa : public Ww1SingleSprmWord { +public: + Ww1SingleSprmPDxa(sal_Char* sName) : + Ww1SingleSprmWord(sName) { + } + void Stop(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPDxaRight : public Ww1SingleSprmPDxa { +public: + Ww1SingleSprmPDxaRight(sal_Char* sName) : + Ww1SingleSprmPDxa(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPDxaLeft : public Ww1SingleSprmPDxa { +public: + Ww1SingleSprmPDxaLeft(sal_Char* sName) : + Ww1SingleSprmPDxa(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPDxaLeft1 : public Ww1SingleSprmPDxa { +public: + Ww1SingleSprmPDxaLeft1(sal_Char* sName) : + Ww1SingleSprmPDxa(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPFKeep : public Ww1SingleSprmBool { +public: + Ww1SingleSprmPFKeep(sal_Char* sName) : + Ww1SingleSprmBool(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); + void Stop(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPFKeepFollow : public Ww1SingleSprmBool { +public: + Ww1SingleSprmPFKeepFollow(sal_Char* sName) : + Ww1SingleSprmBool(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); + void Stop(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPPageBreakBefore : public Ww1SingleSprmBool { +public: + Ww1SingleSprmPPageBreakBefore(sal_Char* sName) : + Ww1SingleSprmBool(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); + void Stop(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPBrc : public Ww1SingleSprmWord { +protected: +// SvxBorderLine* SetBorder(SvxBorderLine*, W1_BRC*); + // spezielle start-routine, je nach sprm verschieden versorgt + // mit einem BoxItem. + void Start(Ww1Shell&, BYTE, W1_BRC10*, USHORT, Ww1Manager&, SvxBoxItem&); + void Start(Ww1Shell&, BYTE, W1_BRC*, USHORT, Ww1Manager&, SvxBoxItem&); + + using Ww1SingleSprm::Start; + +public: + Ww1SingleSprmPBrc(sal_Char* sName) : + Ww1SingleSprmWord(sName) { + } + void Stop(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); + // SetBorder() wird auch fuer Tabellen gebraucht, deshalb public + static SvxBorderLine* SetBorder(SvxBorderLine*, W1_BRC10*); +}; + +#define BRC_TOP ((USHORT)0) +#define BRC_LEFT ((USHORT)1) +#define BRC_BOTTOM ((USHORT)2) +#define BRC_RIGHT ((USHORT)3) +#define BRC_ANZ ((USHORT)BRC_RIGHT-BRC_TOP+1) + +// Die BRC-struktur fuer 1.0 versionen von word sind verschieden von +// denen der folgenden versionen. diese werden zum glueck aber auch +// von anderen sprms abgerufen. +// SH: Ab sofort alle 4 Umrandungen ueber nur 1 Klasse. +class Ww1SingleSprmPBrc10 : public Ww1SingleSprmPBrc +{ + USHORT nLine; // BRC_TOP, BRC_LEFT, ... + + using Ww1SingleSprmPBrc::Start; + +public: + Ww1SingleSprmPBrc10(USHORT nL, sal_Char* sName) + : Ww1SingleSprmPBrc(sName), nLine(nL) {} + + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmParaSpace : public Ww1SingleSprmWord { +public: + Ww1SingleSprmParaSpace(sal_Char* sName) + : Ww1SingleSprmWord(sName) {} + void Stop(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPDyaBefore : public Ww1SingleSprmParaSpace { +public: + Ww1SingleSprmPDyaBefore(sal_Char* sName) + : Ww1SingleSprmParaSpace(sName) {} + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPDyaAfter : public Ww1SingleSprmParaSpace { +public: + Ww1SingleSprmPDyaAfter(sal_Char* sName) : + Ww1SingleSprmParaSpace(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPDyaLine : public Ww1SingleSprmWord { +public: + Ww1SingleSprmPDyaLine(sal_Char* sName) : + Ww1SingleSprmWord(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); + void Stop(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPChgTabsPapx : public Ww1SingleSprmByteSized { +public: + Ww1SingleSprmPChgTabsPapx(sal_Char* sName) : + Ww1SingleSprmByteSized(0, sName) { + } + // Size() ist noch nicht aktiviert !! + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); + void Stop(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmSGprfIhdt : public Ww1SingleSprmByte { +public: + Ww1SingleSprmSGprfIhdt(sal_Char* sName) : + Ww1SingleSprmByte(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmSColumns : public Ww1SingleSprmWord { +public: + Ww1SingleSprmSColumns(sal_Char* sName) : + Ww1SingleSprmWord(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPFInTable : public Ww1SingleSprmBool { +public: + Ww1SingleSprmPFInTable(sal_Char* sName) : + Ww1SingleSprmBool(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); + void Stop(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPTtp : public Ww1SingleSprmBool { +public: + Ww1SingleSprmPTtp(sal_Char* sName) : + Ww1SingleSprmBool(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); + void Stop(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmTJc : public Ww1SingleSprmWord { +public: + Ww1SingleSprmTJc(sal_Char* sName) + : Ww1SingleSprmWord(sName) {} +}; + +//class Ww1SingleSprmTDxaLeft : public Ww1SingleSprmWord { +//public: +// Ww1SingleSprmTDxaLeft(sal_Char* sName) : +// Ww1SingleSprmWord(sName) { +// } +// void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +//}; + +class Ww1SingleSprmTDxaGapHalf : public Ww1SingleSprmWord { +public: + Ww1SingleSprmTDxaGapHalf(sal_Char* sName) : + Ww1SingleSprmWord(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmTDefTable10 : public Ww1SingleSprmWordSized { +public: + Ww1SingleSprmTDefTable10(sal_Char* sName) : + Ww1SingleSprmWordSized(0, sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmTDyaRowHeight : public Ww1SingleSprmWord { +public: + Ww1SingleSprmTDyaRowHeight(sal_Char* sName) : + Ww1SingleSprmWord(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +// Klassendefinitionen fuer Tabellen-Fastsave-Attribute +// Da wir kein Fastsave unterstuetzen, brauchen wir's nicht + +// Klassendefinitionen fuer Apos ( == Flys ) + +class Ww1SingleSprmPpc : public Ww1SingleSprmByte { +public: + Ww1SingleSprmPpc(sal_Char* sName) : + Ww1SingleSprmByte(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPDxaAbs : public Ww1SingleSprmWord { +public: + Ww1SingleSprmPDxaAbs(sal_Char* sName) : + Ww1SingleSprmWord(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPDyaAbs : public Ww1SingleSprmWord { +public: + Ww1SingleSprmPDyaAbs(sal_Char* sName) : + Ww1SingleSprmWord(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPDxaWidth : public Ww1SingleSprmWord { +public: + Ww1SingleSprmPDxaWidth(sal_Char* sName) : + Ww1SingleSprmWord(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +class Ww1SingleSprmPFromText : public Ww1SingleSprmWord { +public: + Ww1SingleSprmPFromText(sal_Char* sName) : + Ww1SingleSprmWord(sName) { + } + void Start(Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&); +}; + +////////////////////////////////////////////////////////////////// Sprm +// +// der tatsaechlich in der datei auftretende datentyp Sprm +// +class Ww1Sprm +{ + BOOL ReCalc(); + static Ww1SingleSprm* aTab[256]; + static Ww1SingleSprm* pSingleSprm; +protected: + static void InitTab(); + Ww1SingleSprm& GetTab(USHORT nId) + { + if( !pSingleSprm ) + InitTab(); + return aTab[ nId ] ? *aTab[nId] : *pSingleSprm; + } + + BYTE* p; + USHORT nCountBytes; + BOOL bOK; + USHORT* pArr; + USHORT count; +// ohne Token, mit laengen-byte/word + USHORT GetSize(BYTE nId, BYTE* pSprm); +// mit Token und LaengenByte + USHORT GetSizeBrutto(BYTE* pSprm) { + BYTE nId = *pSprm++; + return GetSize(nId, pSprm) + 1; } +// gibt fuer nTh element id, size & zeiger auf daten: +// BOOL Fill(USHORT, BYTE&, USHORT&, BYTE*&); +public: +// SH: brauche ich public +// gibt fuer nTh element id, size & zeiger auf daten: + BOOL Fill(USHORT, BYTE&, USHORT&, BYTE*&); + + Ww1Sprm(BYTE*, USHORT); + Ww1Sprm(SvStream&, ULONG); + ~Ww1Sprm(); + friend ostream& operator <<(ostream&, Ww1Sprm&); + void Start(Ww1Shell&, Ww1Manager&); + void Start(Ww1Shell&, Ww1Manager&, USHORT); + void Stop(Ww1Shell&, Ww1Manager&); + BOOL IsUsed() { + return nCountBytes != 255; } + USHORT Count() { + return count; } + BOOL GetError() { + return !bOK; } + static void DeinitTab(); +}; + +/////////////////////////////////////////////////////////////// Picture +// +// der wrapper um den datentyp PIC, eine struktur, die am beginn eines +// bild-dateinamens oder eines eingebetteten bildes steht. +// +class Ww1Picture +{ + BOOL bOK; + W1_PIC* pPic; +public: + Ww1Picture(SvStream&, ULONG); + ~Ww1Picture() { + } + BOOL GetError() { + return !bOK; } + friend ostream& operator <<(ostream&, Ww1Picture&); + void Out(Ww1Shell&, Ww1Manager&); + void WriteBmp(SvStream&); +}; + +/////////////////////////////////////////////////////////////////// Plc +// +// eine der wichtigen array-strukturen der ww-dateien. sie beinhalten +// n+1 dateipositionen und n attribute, die zwischen den +// dateipositionen gelten. +// +class Ww1Plc +{ + BYTE* p; + USHORT nCountBytes; + USHORT iMac; + USHORT nItemSize; + BOOL bOK; +protected: + Ww1Fib& rFib; + BYTE* GetData(USHORT); +public: + Ww1Plc(Ww1Fib&, ULONG, USHORT, USHORT); + ~Ww1Plc(); + friend ostream& operator <<(ostream&, Ww1Plc&); + ULONG Where(USHORT); // wie im jeweiligen plc + void Seek(ULONG, USHORT&); + void Fill(USHORT nIndex, ULONG& begin, ULONG& end) { + begin = Where(nIndex); + end = Where(nIndex+1); } + USHORT Count() { + return iMac; } + BOOL GetError() { + return !bOK; } +}; + +// Size Tabs from Sven: +// CHP, PAP, SEP, HED, FNR, FNT +//Plc 2, 2, 6, 0, 2, 0 +//Fkp 1, 1, 0, 0, 0, 0 + +/////////////////////////////////////////////////////////// PlcGlossary +class Ww1PlcGlossary : public Ww1Plc +{ +public: + Ww1PlcGlossary(Ww1Fib& rFibL) : + Ww1Plc(rFibL, rFibL.GetFIB().fcPlcfglsyGet(), + rFibL.GetFIB().cbPlcfglsyGet(), 0) { + } +}; + +////////////////////////////////////////////////////// PlcAnnotationRef +class Ww1PlcAnnotationRef : public Ww1Plc +{ +public: + Ww1PlcAnnotationRef(Ww1Fib& rFibL) : + Ww1Plc(rFibL, rFibL.GetFIB().fcPlcfandRefGet(), + rFibL.GetFIB().cbPlcfandRefGet(), 0) { + } +}; + +////////////////////////////////////////////////////// PlcAnnotationTxt +class Ww1PlcAnnotationTxt : public Ww1Plc +{ +public: + Ww1PlcAnnotationTxt(Ww1Fib& rFibL) : + Ww1Plc(rFibL, rFibL.GetFIB().fcPlcfandTxtGet(), + rFibL.GetFIB().cbPlcfandTxtGet(), 0) { + } +}; + +///////////////////////////////////////////////////////// PlcAnnotation +class Ww1Annotation { + Ww1PlcAnnotationRef aRef; + Ww1PlcAnnotationTxt aTxt; +public: + Ww1Annotation(Ww1Fib& rFib) : + aRef(rFib), + aTxt(rFib) { + } + friend ostream& operator <<(ostream&, Ww1Annotation&); +}; + +//////////////////////////////////////////////////////////////// PlcSep +class Ww1PlcSep : public Ww1Plc +{ +public: + Ww1PlcSep(Ww1Fib& rFibL): + Ww1Plc(rFibL, rFibL.GetFIB().fcPlcfsedGet(), + rFibL.GetFIB().cbPlcfsedGet(), 6) { + } + friend ostream& operator <<(ostream&, Ww1PlcSep&); +}; + +//////////////////////////////////////////////////////////////// PlcChp +class Ww1PlcChp : public Ww1Plc +{ +public: + Ww1PlcChp(Ww1Fib& rFibL) : + Ww1Plc(rFibL, rFibL.GetFIB().fcPlcfbteChpxGet(), + rFibL.GetFIB().cbPlcfbteChpxGet(), 2) { + } + friend ostream& operator <<(ostream&, Ww1PlcChp&); +}; + +//////////////////////////////////////////////////////////////// PlcPap +class Ww1PlcPap : public Ww1Plc +{ +public: + Ww1PlcPap(Ww1Fib& rFibL) : + Ww1Plc(rFibL, rFibL.GetFIB().fcPlcfbtePapxGet(), + rFibL.GetFIB().cbPlcfbtePapxGet(), 2) { + } + friend ostream& operator <<(ostream&, Ww1PlcPap&); +}; + +//////////////////////////////////////////////////////// PlcFootnoteRef +class Ww1PlcFootnoteRef : public Ww1Plc +{ +public: + Ww1PlcFootnoteRef(Ww1Fib& rFibL) : + Ww1Plc(rFibL, rFibL.GetFIB().fcPlcffndRefGet(), + rFibL.GetFIB().cbPlcffndRefGet(), 2) { + } + friend ostream& operator <<(ostream&, Ww1PlcFootnoteRef&); +}; + +//////////////////////////////////////////////////////// PlcFootnoteTxt +class Ww1PlcFootnoteTxt : public Ww1Plc +{ +public: + Ww1PlcFootnoteTxt(Ww1Fib& rFibL) : + Ww1Plc(rFibL, rFibL.GetFIB().fcPlcffndTxtGet(), + rFibL.GetFIB().cbPlcffndTxtGet(), 0) { + } + friend ostream& operator <<(ostream&, Ww1PlcFootnoteTxt&); +}; + +///////////////////////////////////////////////////////////// PlcFields +class Ww1PlcFields : public Ww1Plc +{ + //USHORT Fill(USHORT, BYTE&, String&, String&, String&); +public: + Ww1PlcFields(Ww1Fib& rFibL, ULONG start, USHORT nBytes) + : Ww1Plc(rFibL, start, nBytes, 2) + {} + W1_FLD* GetData(USHORT nIndex) + { return (W1_FLD*)Ww1Plc::GetData(nIndex); } + ULONG Where(USHORT nIndex) // absolut im file + { return Ww1Plc::Where(nIndex) + rFib.GetFIB().fcMinGet(); } + friend ostream& operator <<(ostream&, Ww1PlcFields&); +}; + +///////////////////////////////////////////////////////////// PlcBookmarks +class Ww1StringList +{ + sal_Char** pIdxA; + USHORT nMax; +public: + Ww1StringList( SvStream& rSt, ULONG nFc, USHORT nCb ); + ~Ww1StringList() + { if( pIdxA ) { delete pIdxA[0]; delete pIdxA; } } + const String GetStr( USHORT nNum ) const; + USHORT Count() const { return nMax; } + BOOL GetError() const { return (nMax != 0) && !pIdxA; } +}; + +class Ww1PlcBookmarkTxt: public Ww1StringList +{ +public: + Ww1PlcBookmarkTxt(Ww1Fib& rFib) : + Ww1StringList( rFib.GetStream(), rFib.GetFIB().fcSttbfbkmkGet(), + rFib.GetFIB().cbSttbfbkmkGet() ) + {} +}; + +class Ww1PlcBookmarkPos : public Ww1Plc +{ +// USHORT Fill(USHORT, BYTE&, String&, String&, String&); +public: + Ww1PlcBookmarkPos(Ww1Fib& _rFib, ULONG start, USHORT nBytes, BOOL bEnd) + : Ww1Plc(_rFib, start, nBytes, (bEnd) ? 0 : 2) + {} + + BYTE* GetData(USHORT nIndex) { return Ww1Plc::GetData(nIndex); } + // Position als CP + ULONG WhereCP(USHORT nIndex) { return Ww1Plc::Where(nIndex); } + // absolut im file + ULONG Where(USHORT nIndex) + { + return ( nIndex < Count() ) + ? Ww1Plc::Where(nIndex) + rFib.GetFIB().fcMinGet() + : 0xffffffff; + } +// friend ostream& operator <<(ostream&, Ww1PlcBookmarks&); +}; + +//////////////////////////////////////////////////////////////// PlcHdd +class Ww1PlcHdd : public Ww1Plc +{ +public: + Ww1PlcHdd(Ww1Fib& rFibL) + : Ww1Plc(rFibL, rFibL.GetFIB().fcPlcfhddGet(), + rFibL.GetFIB().cbPlcfhddGet(), 0) + {} +}; + +/////////////////////////////////////////////////////////////////// Fkp +// +// aehnlich den plcs aufgebaute arrays, die sich auf eine groesze von +// 512 byte beschraenken. +// +class Ww1Fkp +{ +protected: + BYTE aFkp[512]; + USHORT nItemSize; + BOOL bOK; + BYTE* GetData(USHORT); +public: + Ww1Fkp(SvStream&, ULONG, USHORT); + friend ostream& operator <<(ostream&, Ww1Fkp&); + USHORT Count() const { return SVBT8ToByte(aFkp+511); } + ULONG Where(USHORT); // wie im entsprechenden fkp +}; + +//////////////////////////////////////////////////////////////// FkpPap +class Ww1FkpPap : public Ww1Fkp +{ +public: + Ww1FkpPap(SvStream& rStream, ULONG ulFilePos) + : Ww1Fkp(rStream, ulFilePos, 1) + {} + friend ostream& operator <<(ostream&, Ww1FkpPap&); + BOOL Fill(USHORT, BYTE*&, USHORT&); +}; + +//////////////////////////////////////////////////////////////// FkpChp +class Ww1FkpChp : public Ww1Fkp +{ +#ifdef DUMP + SvStream& rStream; + SvStream& GetStream() { return rStream; } +#endif +public: + Ww1FkpChp(SvStream& rStream, ULONG ulFilePos) + : Ww1Fkp(rStream, ulFilePos, 1) +#ifdef DUMP + , rStream(rStream) +#endif + {} + + friend ostream& operator <<(ostream&, Ww1FkpChp&); + BOOL Fill(USHORT, W1_CHP&); +}; + +////////////////////////////////////////////////////////////// SprmPapx +class Ww1SprmPapx : public Ww1Sprm +{ + W1_PAPX aPapx; + BYTE* Sprm(BYTE* p, USHORT nSize); + USHORT SprmSize(BYTE* p, USHORT nSize); +public: + Ww1SprmPapx(BYTE* p, USHORT nSize); + friend ostream& operator <<(ostream&, Ww1SprmPapx&); + void Start(Ww1Shell&, Ww1Manager&); + void Stop(Ww1Shell&, Ww1Manager&); +}; + +/////////////////////////////////////////////////////////////// SprmSep +class Ww1SprmSep : public Ww1Sprm +{ +public: + Ww1SprmSep(Ww1Fib& rFib, ULONG ulFilePos) + : Ww1Sprm(rFib.GetStream(), ulFilePos) + {} + friend ostream& operator <<(ostream&, Ww1SprmSep&); +}; + +///////////////////////////////////////////////////////////////// Assoc +class Ww1Assoc +{ + enum fields { FileNext, Dot, Title, Subject, KeyWords, Comments, + Author, LastRevBy, DataDoc, HeaderDoc, Criteria1, Criteria2, + Criteria3, Criteria4, Criteria5, Criteria6, Criteria7, MaxFields }; + + Ww1Fib& rFib; + sal_Char* pBuffer; + sal_Char* pStrTbl[ MaxFields ]; + BOOL bOK; + + String GetStr(USHORT); + +public: + Ww1Assoc(Ww1Fib&); + ~Ww1Assoc() { delete pBuffer; } + BOOL GetError() const { return !bOK; } + friend ostream& operator <<(ostream&, Ww1Assoc&); + void Out(Ww1Shell&); +}; + +////////////////////////////////////////////////////////// HeaderFooter +// +// Header/Footer/Footnoteseparators sind einer nach dem naechsten in +// einem eigenen text gespeichert. ein plc trennt diesen text in +// einzelne teile. diese werden durchnummeriert als ihdd. nun gibt es +// 9 verschiedene funktionen fuer diese texte. wird eine davon +// angefordert, ist es der erste, beim naechstern der 2 ihdd und so +// weiter. welcher textteil also welcher typ sein wird laeszt sich +// nur bei sequenziellem lesen der datei bestimmen. die 9 typen sind: +// fusznoten-trenner, folge-fusznoten-trenner, folge-fusznoten-notiz, +// gerade-seiten kopfzeilen, ungerade seiten kopfzeilen, dto 2* +// fuszzeilen, kopf & fuszzeilen, wenn erste seite andere zeilen hat. +// HeaderFooter merkt sich fuer jede der 9 die momentane einstellung +// (jedoch nicht die alten) und den naechstvergebbaren ihdd. ist ein +// teil nicht vorhanden bekommt er den wert 0xffff. +// +class Ww1HeaderFooter : public Ww1PlcHdd +{ + USHORT nextIhdd; // naechster textteil im HddText + USHORT nFtnSep; // fusznoten trenner + USHORT nFtnFollowSep; // folge fusznoten trenner + USHORT nFtnNote; // folgefunsznotennotiz + USHORT nEvenHeadL; // kopfzeilen grader seiten + USHORT nOddHeadL; // kopfzeilen ungrader seiten + USHORT nEvenFootL; // fuszzeilen grader seiten + USHORT nOddFootL; // fuszzeilen ungerader seiten + USHORT nFirstHeadL; // kopfzeilen der ersten seite + USHORT nFirstFootL; // fuszzeilen der ersten seite + enum HeaderFooterMode { + None, FtnSep, FtnFollowSep, FtnNote, EvenHeadL, OddHeadL, + EvenFootL, OddFootL, FirstHeadL, MaxHeaderFooterMode + } eHeaderFooterMode; + +public: + Ww1HeaderFooter(Ww1Fib& rFibL, USHORT grpfIhdt) + : Ww1PlcHdd(rFibL), + nextIhdd(0), + nFtnSep(0xffff), + nFtnFollowSep(0xffff), + nFtnNote(0xffff), + nEvenHeadL(0xffff), + nOddHeadL(0xffff), + nEvenFootL(0xffff), + nOddFootL(0xffff), + nFirstHeadL(0xffff), + nFirstFootL(0xffff), + eHeaderFooterMode(None) + { + if (grpfIhdt & 0x0001) nFtnSep = nextIhdd++; + if (grpfIhdt & 0x0002) nFtnFollowSep = nextIhdd++; + if (grpfIhdt & 0x0004) nFtnNote = nextIhdd++; + } +// ~Ww1HeaderFooter() {} + void SetGrpfIhdt(USHORT grpfIhdt) + { + if (grpfIhdt & 0x0001) nEvenHeadL = nextIhdd++; + if (grpfIhdt & 0x0002) nOddHeadL = nextIhdd++; + if (grpfIhdt & 0x0004) nEvenFootL = nextIhdd++; + if (grpfIhdt & 0x0008) nOddFootL = nextIhdd++; + if (grpfIhdt & 0x0010) nFirstHeadL = nextIhdd++; + if (grpfIhdt & 0x0020) nFirstFootL = nextIhdd++; + DBG_ASSERT(nextIhdd<=Count(), "Ww1HeaderFooter"); + } + BOOL operator++(int) + { + BOOL bRet = TRUE; + eHeaderFooterMode = (HeaderFooterMode)((short)eHeaderFooterMode + 1); + if( eHeaderFooterMode == MaxHeaderFooterMode) + { + eHeaderFooterMode = None; + bRet = FALSE; + } + return bRet; + } + BOOL FillFtnSep(ULONG& begin, ULONG& end) + { + if (nFtnSep == 0xffff) + return FALSE; + Fill(nFtnSep, begin, end); + return TRUE; + } + BOOL FillFtnFollowSep(ULONG& begin, ULONG& end) + { + if (nFtnFollowSep == 0xffff) + return FALSE; + Fill(nFtnFollowSep, begin, end); + return TRUE; + } + BOOL FillFtnNote(ULONG& begin, ULONG& end) + { + if (nFtnNote == 0xffff) + return FALSE; + Fill(nFtnNote, begin, end); + return TRUE; + } + BOOL FillEvenHeadL(ULONG& begin, ULONG& end) + { + if (nEvenHeadL == 0xffff) + return FALSE; + Fill(nEvenHeadL, begin, end); + return TRUE; + } + BOOL FillOddHeadL(ULONG& begin, ULONG& end) + { + if (nOddHeadL == 0xffff) + return FALSE; + Fill(nOddHeadL, begin, end); + return TRUE; + } + BOOL FillEvenFootL(ULONG& begin, ULONG& end) + { + if (nEvenFootL == 0xffff) + return FALSE; + Fill(nEvenFootL, begin, end); + return TRUE; + } + BOOL FillOddFootL(ULONG& begin, ULONG& end) + { + if (nOddFootL == 0xffff) + return FALSE; + Fill(nOddFootL, begin, end); + return TRUE; + } + BOOL FillFirstHeadL(ULONG& begin, ULONG& end) + { + if (nFirstHeadL == 0xffff) + return FALSE; + Fill(nFirstHeadL, begin, end); + return TRUE; + } + BOOL FillFirstFootL(ULONG& begin, ULONG& end) + { + if (nFirstFootL == 0xffff) + return FALSE; + Fill(nFirstFootL, begin, end); + return TRUE; + } + void Start(Ww1Shell&, Ww1Manager&); + void Stop(Ww1Shell&, Ww1Manager&, sal_Unicode&); +}; + +//////////////////////////////////////////////////////////////// Fields +class Ww1Fields : public Ww1PlcFields +{ + USHORT nPlcIndex; + String sErgebnis; // das von word errechnete ergebniss + SwField* pField; + ULONG Where(USHORT nIndex) // innerhalb des textes + { return Ww1PlcFields::Where(nIndex) - rFib.GetFIB().fcMinGet(); } + +public: + Ww1Fields(Ww1Fib& rFibL, ULONG ulFilePos, USHORT nBytes) + : Ww1PlcFields(rFibL, ulFilePos, nBytes), nPlcIndex(0), pField(0) + {} +// ~Ww1Fields() {} + // innerhalb des textes + ULONG Where() { return Where(nPlcIndex); } + void operator++(int) + { + DBG_ASSERT(nPlcIndex+1 <= Count(), "Ww1Fields"); + nPlcIndex++; + } + void Seek(ULONG ulNew) { Ww1PlcFields::Seek(ulNew, nPlcIndex); } + W1_FLD* GetData() + { + DBG_ASSERT(nPlcIndex < Count(), "Ww1Fields"); + return Ww1PlcFields::GetData(nPlcIndex); + } + ULONG GetLength(); + friend ostream& operator <<(ostream&, Ww1Manager&); + void Start(Ww1Shell&, Ww1Manager&); + void Stop(Ww1Shell&, Ww1Manager&, sal_Unicode&); + void Out(Ww1Shell&, Ww1Manager&, USHORT=0); +}; + +class Ww1TextFields : public Ww1Fields +{ +public: + Ww1TextFields(Ww1Fib& rFibL) + : Ww1Fields(rFibL, rFibL.GetFIB().fcPlcffldMomGet(), + rFibL.GetFIB().cbPlcffldMomGet()) + {} +}; + +class Ww1FootnoteFields : public Ww1Fields +{ +public: + Ww1FootnoteFields(Ww1Fib& rFibL) + : Ww1Fields(rFibL, rFibL.GetFIB().fcPlcffldFtnGet(), + rFibL.GetFIB().cbPlcffldFtnGet()) + {} +}; + +class Ww1HeaderFooterFields : public Ww1Fields +{ +public: + Ww1HeaderFooterFields(Ww1Fib& rFibL) + : Ww1Fields(rFibL, rFibL.GetFIB().fcPlcffldHdrGet(), + rFibL.GetFIB().cbPlcffldHdrGet()) + {} +}; + +class Ww1MacroFields : public Ww1Fields +{ +public: + Ww1MacroFields(Ww1Fib& rFibL) + : Ww1Fields(rFibL, rFibL.GetFIB().fcPlcffldMcrGet(), + rFibL.GetFIB().cbPlcffldMcrGet()) + {} +}; + +//////////////////////////////////////////////////////////////// Bookmarks +class Ww1Bookmarks +{ + Ww1PlcBookmarkTxt aNames; + Ww1PlcBookmarkPos* pPos[2]; + Ww1Fib& rFib; + + USHORT nPlcIdx[2]; + USHORT nIsEnd; + BOOL bOK; +// ULONG Where(USHORT nIndex) { // innerhalb des textes +// return Ww1PlcFields::Where(nIndex) - rFib.GetFIB().fcMinGet(); } +public: + Ww1Bookmarks(Ww1Fib& rFib); + ~Ww1Bookmarks() + { + delete pPos[1]; + delete pPos[0]; + } + ULONG Where() const { return pPos[nIsEnd]->WhereCP(nPlcIdx[nIsEnd]); } + void operator++(int); + BOOL GetError() const { return !bOK; } + long GetHandle() const; + BOOL GetIsEnd() const { return ( nIsEnd ) ? TRUE : FALSE; } + const String GetName() const; + long Len() const; + friend ostream& operator <<(ostream&, Ww1Bookmarks&); + void Start(Ww1Shell&, Ww1Manager&); + void Stop(Ww1Shell&, Ww1Manager&, sal_Unicode&); + void Out(Ww1Shell&, Ww1Manager&, USHORT=0); +}; + +///////////////////////////////////////////////////////////// Footnotes +class Ww1Footnotes : public Ww1PlcFootnoteRef +{ + USHORT nPlcIndex; + Ww1PlcFootnoteTxt aText; + BOOL bStarted; +public: + Ww1Footnotes(Ww1Fib& rFibL) + : Ww1PlcFootnoteRef(rFibL), nPlcIndex(0), aText(rFibL), bStarted(FALSE) + {} +// ~Ww1Footnotes() {} + // innerhalb des textes + ULONG Where() + { + ULONG ulRet = 0xffffffff; + if (Count()) + ulRet = Ww1PlcFootnoteRef::Where(nPlcIndex); + return ulRet; + } + void operator++(int) + { + DBG_ASSERT(nPlcIndex+1 <= Count(), "Ww1Footnotes"); + nPlcIndex++; + } + void Start(Ww1Shell&, Ww1Manager&); + void Stop(Ww1Shell&, Ww1Manager&, sal_Unicode&); +}; + +/////////////////////////////////////////////////////////////////// Sep +class Ww1Sep : public Ww1PlcSep +{ + Ww1HeaderFooter aHdd; + USHORT nPlcIndex; +public: + Ww1Sep(Ww1Fib& rFibL, USHORT grpfIhdt) + : Ww1PlcSep(rFibL), aHdd(rFibL, grpfIhdt), nPlcIndex(0) {} + + Ww1HeaderFooter& GetHdd() { return aHdd; } + void operator++(int) { nPlcIndex++; } + BYTE* GetData() { return Ww1PlcSep::GetData(nPlcIndex); } + // innerhalb des textes + ULONG Where() { return Ww1PlcSep::Where(nPlcIndex); } + void SetGrpfIhdt(BYTE grpfIhdt) + { + GetHdd().SetGrpfIhdt(grpfIhdt); +// GetHdd().Start(rOut, rMan); + } + void Start(Ww1Shell&, Ww1Manager&); + void Stop(Ww1Shell& rOut, Ww1Manager& rMan, sal_Unicode& c) + { aHdd.Stop(rOut, rMan, c); } +}; + +/////////////////////////////////////////////////////////////////// Pap +class Ww1Pap : public Ww1PlcPap +{ + USHORT nPlcIndex; + USHORT nPushedPlcIndex; + USHORT nFkpIndex; + USHORT nPushedFkpIndex; + ULONG ulOffset; + Ww1FkpPap* pPap; + + BOOL FindSprm(USHORT nId, BYTE* pStart, BYTE* pEnd); + void UpdateIdx() + { + if (pPap && nFkpIndex >= pPap->Count() ) + { + delete pPap; + pPap = NULL; + nPlcIndex++; + } + if( !pPap ) + Where(); + } + BOOL HasId0(USHORT nId); + +public: + Ww1Pap(Ww1Fib& rFib); + ~Ww1Pap() { delete pPap; } + ULONG Where( BOOL bSetIndex = TRUE ); // innerhalb des textes + void operator++(int); + BOOL FillStart(BYTE*& pB, USHORT& nSize) + { + UpdateIdx(); + return pPap->Fill(nFkpIndex, pB, nSize); + } + BOOL FillStop(BYTE*& pB, USHORT& nSize) + { + return nFkpIndex ? pPap->Fill(nFkpIndex-1, pB, nSize) : FALSE; + } + void Start(Ww1Shell&, Ww1Manager&); + void Stop(Ww1Shell&, Ww1Manager&, sal_Unicode&); + void Seek(ULONG); + void Push(ULONG ulOffsetTmp = 0) + { + DBG_ASSERT(!Pushed(), "Ww1Pap"); + nPushedPlcIndex = nPlcIndex; + nPushedFkpIndex = nFkpIndex; + Seek(ulOffsetTmp); + ulOffset = ulOffsetTmp; + delete pPap; + pPap = NULL; + } + BOOL Pushed() + { + return nPushedPlcIndex != 0xffff; + } + void Pop() + { + DBG_ASSERT(Pushed(), "Ww1Pap"); + ulOffset = 0; + nPlcIndex = nPushedPlcIndex; + nFkpIndex = nPushedFkpIndex; + nPushedPlcIndex = 0xffff; + nPushedFkpIndex = 0xffff; + delete pPap; + pPap = NULL; + Where( FALSE ); + } + BOOL HasId(USHORT nId); +}; + +/////////////////////////////////////////////////////////////////// Chp +class Ww1Chp : public Ww1PlcChp +{ + USHORT nPlcIndex; + USHORT nPushedPlcIndex; + USHORT nFkpIndex; + USHORT nPushedFkpIndex; + ULONG ulOffset; + Ww1FkpChp* pChp; + void UpdateIdx() + { + if (pChp && nFkpIndex >= pChp->Count() ) + { + delete pChp; + pChp = NULL; + nPlcIndex++; + } + if( !pChp ) + Where(); + } + +public: + Ww1Chp( Ww1Fib& rFib ); + ~Ww1Chp() { delete pChp; } + ULONG Where( BOOL bSetIndex = TRUE ); // innerhalb des textes + void operator++(int); + BOOL FillStart(W1_CHP& rChp) + { + UpdateIdx(); + return pChp->Fill(nFkpIndex, rChp); + } + BOOL FillStop(W1_CHP& rChp) + { return nFkpIndex ? pChp->Fill(nFkpIndex-1, rChp) : FALSE; } + void Start(Ww1Shell&, Ww1Manager&); + void Stop(Ww1Shell&, Ww1Manager&, sal_Unicode&); + void Seek(ULONG); + void Push(ULONG ulOffsetTmp = 0) + { + DBG_ASSERT(!Pushed(), "Ww1Chp"); + nPushedPlcIndex = nPlcIndex; + nPushedFkpIndex = nFkpIndex; + Seek(ulOffsetTmp); + ulOffset = ulOffsetTmp; + delete pChp; + pChp = NULL; + } + BOOL Pushed() { return nPushedPlcIndex != 0xffff; } + void Pop() + { + DBG_ASSERT(Pushed(), "Ww1Chp"); + ulOffset = 0; + nPlcIndex = nPushedPlcIndex; + nFkpIndex = nPushedFkpIndex; + nPushedPlcIndex = 0xffff; + nPushedFkpIndex = 0xffff; + delete pChp; + pChp = NULL; + Where( FALSE ); + } +}; + +/////////////////////////////////////////////////////////////// Manager +// +// zentraler aufhaenger der ww-seite des filters, konstruiert aus dem +// inputstream (ww-datei) enthaelt er alles, was noetig ist, um in die +// shell (pm-seite) gepiped zu werden. +// +class Ww1Manager +{ + BOOL bOK; + BOOL bInTtp; + BOOL bInStyle; + BOOL bStopAll; + Ww1Fib aFib; + Ww1Dop aDop; + Ww1Fonts aFonts; +// ab jetzt alles paarig, fuer 'pushed': + Ww1DocText aDoc; + Ww1PlainText* pDoc; + ULONG ulDocSeek; + ULONG* pSeek; + Ww1TextFields aFld; + Ww1Fields* pFld; +// selbst 'push'bar: + Ww1Chp aChp; + Ww1Pap aPap; +// nicht in textbereichen vorhanden, wenn ge'pushed' + Ww1Footnotes aFtn; + Ww1Bookmarks aBooks; + Ww1Sep aSep; + + void OutStop( Ww1Shell&, sal_Unicode ); + void OutStart( Ww1Shell& ); + void Out(Ww1Shell&, sal_Unicode ); + +public: + Ww1Manager(SvStream& rStrm, ULONG nFieldFlgs); + BOOL GetError() const { return !bOK; } + +// Fuer Tabellen + void SetInTtp(BOOL bSet = TRUE) { bInTtp = bSet; } + BOOL IsInTtp() const { return bInTtp; } + void SetInStyle(BOOL bSet = TRUE) { bInStyle = bSet; } + BOOL IsInStyle() const { return bInStyle; } + void SetStopAll(BOOL bSet = TRUE) { bStopAll = bSet; } + BOOL IsStopAll() const { return bStopAll; } + BOOL HasInTable(); + BOOL HasTtp(); + BOOL LastHasTtp(); + +// Fuer Flys + BOOL HasPPc(); + BOOL HasPDxaAbs(); + + Ww1Fib& GetFib() { return aFib; } + Ww1PlainText& GetText() { return *pDoc; } + Ww1Dop& GetDop() { return aDop; } + Ww1Sep& GetSep() { return aSep; } + // innerhalb des textes + ULONG Where() { return pDoc->Where(); } + void Fill( sal_Unicode& rChr ) { pDoc->Out( rChr ); } + BYTE Fill( String& rStr, ULONG ulLen) + { + ulLen += pDoc->Where(); + return sal::static_int_cast< BYTE >(pDoc->Out(rStr, ulLen)); + } + SvxFontItem GetFont(USHORT nFCode); + friend Ww1Shell& operator <<(Ww1Shell&, Ww1Manager&); + friend ostream& operator <<(ostream&, Ww1Manager&); + BOOL Pushed() { return pDoc != &aDoc; } + void Pop(); + void Push0(Ww1PlainText* pDoc, ULONG, Ww1Fields* = 0); + void Push1(Ww1PlainText* pDoc, ULONG ulSeek, ULONG ulSeek2 = 0, + Ww1Fields* = 0); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww1/w1filter.cxx b/sw/source/filter/ww1/w1filter.cxx new file mode 100644 index 000000000000..d494d20b85e8 --- /dev/null +++ b/sw/source/filter/ww1/w1filter.cxx @@ -0,0 +1,2028 @@ +/* -*- 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" +#include <hintids.hxx> + +#include <tools/solar.h> +#include <comphelper/string.hxx> +#include <editeng/paperinf.hxx> +#include <svtools/filter.hxx> +#include <vcl/graph.hxx> +#include <editeng/fontitem.hxx> +#include <editeng/lrspitem.hxx> +#include <editeng/ulspitem.hxx> +#include <editeng/wghtitem.hxx> +#include <editeng/postitem.hxx> +#include <editeng/crsditem.hxx> +#include <editeng/cntritem.hxx> +#include <editeng/cmapitem.hxx> +#include <editeng/fhgtitem.hxx> +#include <editeng/udlnitem.hxx> +#include <editeng/wrlmitem.hxx> +#include <editeng/colritem.hxx> +#include <editeng/kernitem.hxx> +#include <editeng/escpitem.hxx> +#include <editeng/tstpitem.hxx> +#include <svl/urihelper.hxx> +#include <fmtfsize.hxx> +#include <doc.hxx> +#include <pam.hxx> +#include <ndtxt.hxx> +#include <pagedesc.hxx> +#include <flddat.hxx> +#include <reffld.hxx> +#include <expfld.hxx> +#include <docufld.hxx> +#include <ftninfo.hxx> +#include <section.hxx> // class SwSection +#include <fltini.hxx> +#include <w1par.hxx> + +#include <docsh.hxx> +#include <swerror.h> +#include <mdiexp.hxx> +#include <statstr.hrc> +#if OSL_DEBUG_LEVEL > 1 +#include <stdio.h> +#endif + +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include <com/sun/star/document/XDocumentProperties.hpp> + +#define MAX_FIELDLEN 64000 + +using namespace nsSwDocInfoSubType; + + +/////////////////////////////////////////////////////////////////////// +// +// hier stehen die methoden operator<<, Out, Start und Stop mit +// folgender Bedeutung: wenn moeglich wird die information aus dem +// dokument per +// operator<<() +// in die shell uebertragen. sind jedoch weitere parameter noetig +// wurde der name +// Out() +// gewaehlt. ist ein bereich zu kennzeichnen (zB bei attributen +// von/bis), heissen die methoden +// Start(), Stop() +// alle diese methoden stehen in diesem modul, das fuer den filter, +// jedoch nicht fuer den dumper noetig ist. und da alle regeln ihre +// ausnahme haben: hier stehen auch methoden, die aus anderen gruenden +// fuer den dumper sinnlos sind, zB wenn sie auf sv-strukturen beruhen +// wie zB GetFont() auf SvxFontItem. +// + +/////////////////////////////////////////////////////////////// Manager +Ww1Shell& operator <<(Ww1Shell& rOut, Ww1Manager& This) +{ + // verhindern, das bei rekusivem aufruf dies mehrfach passiert: + if (!This.Pushed()) + { + { // der wird nur temporaer gebraucht: + This.SetInStyle( TRUE ); + Ww1StyleSheet(This.aFib).Out(rOut, This); + This.SetInStyle( FALSE ); + } + { // dieser auch: + Ww1Assoc(This.aFib).Out(rOut); + } + // dieser nicht, der ist bereits member: + This.aDop.Out(rOut); + // Jetzt entscheiden, wie Seitenvorlagen erzeugt werden + if (This.GetSep().Count() <= 1) + rOut.SetUseStdPageDesc(); + } + // und jetzt das eigentliche dok: + sal_Unicode cUnknown = ' '; + while (*This.pSeek < This.pDoc->Count()) + { + // ausgabe des ProgressState nur, wenn im haupttext, da sonst + // nicht bestimmt werden kann, wie weit wir sind: + if (!This.Pushed()) + ::SetProgressState(This.Where() * 100 / This.pDoc->Count(), + rOut.GetDoc().GetDocShell()); + // hier werden abwechselnd die attribute und die zeichen in die + // shell gepumpt. die positionen werden durch das lesen der + // zeichen aus dem manager hoch- gezaehlt. erst alle attribute: + This.Out(rOut, cUnknown); + // das textdocument pDoc ist ein Ww1PlainText, dessen Out() + // methode solange ausgibt, bis entweder ein sonderzeichen + // auftaucht oder die anzahl der auszugebenden zeichen erreicht + // ist: + cUnknown = This.pDoc->Out(rOut, *This.pSeek); + } + This.SetStopAll(TRUE); + This.OutStop(rOut, cUnknown); // Damit die Attribute am Ende geschlossen + This.SetStopAll(FALSE); // werden + return rOut; +} + +void Ww1Manager::OutStop(Ww1Shell& rOut, sal_Unicode cUnknown) +{ + // Bookmarks brauchen nicht beendet werden ??? + if (pFld) + pFld->Stop(rOut, *this, cUnknown); + if (!Pushed()) + aFtn.Stop(rOut, *this, cUnknown); + if (1) + aChp.Stop(rOut, *this, cUnknown); + if (1) + aPap.Stop(rOut, *this, cUnknown); + if (!Pushed()) + aSep.Stop(rOut, *this, cUnknown); +} + +void Ww1Manager::OutStart( Ww1Shell& rOut ) +{ +// alle attribute, die's brauchen beginnen + if (!Pushed()) + aSep.Start(rOut, *this); + if (1) + aPap.Start(rOut, *this); + if (1) + aChp.Start(rOut, *this); + if (!Pushed()) + aFtn.Start(rOut, *this); + if (pFld) + pFld->Start(rOut, *this); + if (!Pushed()) + aBooks.Start(rOut, *this); +// bestimmen, wo das naechste Ereigniss ist: + ULONG ulEnd = pDoc->Count(); // spaetestens am textende + if (!Pushed()) + if (ulEnd > aSep.Where()) // naechster Sep vorher? + ulEnd = aSep.Where(); + if (1) + if (ulEnd > aPap.Where()) // naechster Pap vorher? + ulEnd = aPap.Where(); + if (1) + if (ulEnd > aChp.Where()) // naechster Chp vorher? + ulEnd = aChp.Where(); + if (!Pushed()) + if (ulEnd > aFtn.Where()) // naechster Ftn vorher? + ulEnd = aFtn.Where(); + if (pFld) + if (ulEnd > pFld->Where()) // naechster Fld vorher? + ulEnd = pFld->Where(); + if (!Pushed()) + if (ulEnd > aBooks.Where()) // naechster Bookmark vorher? + ulEnd = aBooks.Where(); + *pSeek = Where(); // momentane position + if (*pSeek < ulEnd) // sind wir bereits weiter? + *pSeek = ulEnd; +} + +void Ww1Manager::Out(Ww1Shell& rOut, sal_Unicode cUnknown) +{ +// Je nach modus wird hier mit feldern, fusznoten, zeichenattributen, +// absatzatributen und sektionen wie folgt verfahren: von allen wird +// zuallererst die stop-methoden gerufen. stellt das objekt fest, dasz +// etwas zu beenden ist (natuerlich nicht im ersten durchgang) beendet +// es dies, ansonsten ist der aufruf wirkungslos. dann werden +// unbehandelte sonderzeichen augegeben. das werden genauso alle +// start-methoden gerufen und danach per where festgestellt, an +// welcher stelle die naechste aktion zu erwarten ist. +// +// ist der manager in einem ge'push'ten mode, werden bestimmte +// elemente ausgeklammert. felder werden wiederum nur in besonderen +// faellen augeklammert, wenn naemlich bereiche ausgegeben werden, die +// keine felder enthalten koennen. charakterattribute und +// paragraphenattribute werden jedoch nie ausgeklammert. die if (1) +// wurden zur verdeutlichung der einheitlichkeit eingefuegt. + +// Erstmal eine Sonderbehandlung fuer Tabellen: +// die wichtigen Attribute lassen sich am Besten vor Beendigung derselben +// abfragen. +// Optimierung: Sie werden nur auf sinnvolle Werte gesetzt, wenn +// das 0x07-Zeiche ansteht. + + BOOL bLIsTtp = FALSE; + BOOL bLHasTtp = FALSE; + if( cUnknown == 0x07 ) + { + bLIsTtp = IsInTtp(); + bLHasTtp = HasTtp(); + } + + OutStop( rOut, cUnknown ); // Attrs ggfs. beenden + +// meta-zeichen interpretieren: + if (!Ww1PlainText::IsChar(cUnknown)) + switch (cUnknown) + { + case 0x02: + // dontknow + break; + case 0x07: // table + if (rOut.IsInTable() && HasInTable() && !bLIsTtp && !bLHasTtp) + rOut.NextTableCell(); + break; + case 0x09: // tab + rOut.NextTab(); + break; + case 0x0a: // linefeed + rOut.NextParagraph(); + break; + case 0x0b: // linebreak + if (rOut.IsInTable()) + ; + else + rOut.NextLine(); + break; + case 0x0d: // carriage return + // ignore + break; + case 0x0c: // pagebreak + rOut.NextPage(); + break; + case 0x14: // sectionendchar + // ignore here + break; + default: + break; + } + + OutStart( rOut ); // Attrs ggfs. starten und Naechste Pos berechnen +} + +SvxFontItem Ww1Manager::GetFont(USHORT nFCode) +{ + return aFonts.GetFont(nFCode); +} + +void Ww1Manager::Push0(Ww1PlainText* _pDoc, ULONG ulSeek, Ww1Fields* _pFld) +{ + DBG_ASSERT(!Pushed(), "Ww1Manager"); + this->pDoc = _pDoc; + pSeek = new ULONG; + *pSeek = pDoc->Where(); + aPap.Push(ulSeek); + aChp.Push(ulSeek); + this->pFld = _pFld; +} + +// ulSeek ist der FC-Abstand zwischen Hauptest-Start und Sondertext-Start +// ulSeek2 ist der Offset dieses bestimmten Sondertextes im Sondertext-Bereich, +// also z.B. der Offset des speziellen K/F-Textes +void Ww1Manager::Push1(Ww1PlainText* _pDoc, ULONG ulSeek, ULONG ulSeek2, + Ww1Fields* _pFld) +{ + DBG_ASSERT(!Pushed(), "Ww1Manager"); + this->pDoc = _pDoc; + pSeek = new ULONG; + *pSeek = pDoc->Where(); + aPap.Push(ulSeek + ulSeek2); + aChp.Push(ulSeek + ulSeek2); + if( _pFld ) + _pFld->Seek( ulSeek2 ); + this->pFld = _pFld; +} + +void Ww1Manager::Pop() +{ + DBG_ASSERT(Pushed(), "Ww1Manager"); + delete pDoc; + pDoc = &aDoc; + delete pSeek; + pSeek = &ulDocSeek; + aChp.Pop(); + aPap.Pop(); + delete pFld; + pFld = &aFld; +} + +///////////////////////////////////////////////////////////// Bookmarks + +void Ww1Bookmarks::Out(Ww1Shell& rOut, Ww1Manager& rMan, USHORT) +{ + if (GetIsEnd()) + { + rOut.SetBookEnd(GetHandle()); + return; + } + + const String & rName = GetName(); + if( rName.EqualsAscii( "_Toc", 0, 4 ) ) // "_Toc*" ist ueberfluessig + return; + + if( rOut.IsFlagSet( SwFltControlStack::HYPO ) + && rName.EqualsIgnoreCaseAscii( "FORMULAR" ) ) + rOut.SetProtect(); + + // Fuer UEbersetzung Bookmark -> Variable setzen + long nLen = Len(); + if( nLen > MAX_FIELDLEN ) + nLen = MAX_FIELDLEN; + + // Lese Inhalt des Bookmark + // geht vermulich auch ueber Ww1PlainText + String aVal( rMan.GetText().GetText( Where(), nLen ) ); + + // in 2 Schritten, da OS/2 zu doof ist + SwFltBookmark aBook( rName, aVal, GetHandle(), FALSE ); + rOut << aBook; +} + +void Ww1Bookmarks::Start(Ww1Shell& rOut, Ww1Manager& rMan) +{ + if (rMan.Where() >= Where()) + { + Out(rOut, rMan); + (*this)++; + } +} + +///////////////////////////////////////////////////////////// Footnotes +void Ww1Footnotes::Start(Ww1Shell& rOut, Ww1Manager& rMan) +{ + if (rMan.Where() >= Where()) + { + DBG_ASSERT(nPlcIndex < Count(), "WwFootnotes"); + sal_Unicode c; + rMan.Fill(c); + DBG_ASSERT(c==0x02, "Ww1Footnotes"); + if (c==0x02) + { + Ww1FtnText* pText = new Ww1FtnText(rMan.GetFib()); + // beginn des textes dieser fusznote: + ULONG start = aText.Where(nPlcIndex); + pText->Seek(start); + // laenge des textes + ULONG count = aText.Where(nPlcIndex+1) - start; + pText->SetCount(count); + // fusznotenkennung sollte das erste byte sein + pText->Out(c); + DBG_ASSERT(c==0x02, "Ww1Footnotes"); + count--; // fuer das eben gelesene kenn-byte + // fusznoten mode beginnen: + rOut.BeginFootnote(); + bStarted = TRUE; + rMan.Push0(pText, pText->Offset(rMan.GetFib()), + new Ww1FootnoteFields(rMan.GetFib())); + rOut << rMan; + rMan.Pop(); + rOut.EndFootnote(); + } + else + (*this)++; + } +} + +void Ww1Footnotes::Stop(Ww1Shell& /*rOut*/, Ww1Manager& rMan, sal_Unicode& c) +{ + if (bStarted && rMan.Where() > Where()) + { + DBG_ASSERT(nPlcIndex < Count(), "Ww1Footnotes"); + c = ' '; + (*this)++; + } +} + +//////////////////////////////////////////////////////////////// Fields +void Ww1Fields::Start(Ww1Shell& rOut, Ww1Manager& rMan) +{ + if (rMan.Where() >= Where()){ + DBG_ASSERT(nPlcIndex < Count(), "Ww1Fields"); + if (GetData()->chGet() == 19) + Out(rOut, rMan); + else + (*this)++; // ignore + } +} + +void Ww1Fields::Stop( Ww1Shell& rOut, Ww1Manager& rMan, sal_Unicode& c) +{ + if (rMan.Where() >= Where()) + { + DBG_ASSERT(nPlcIndex < Count(), "Ww1Fields"); + if (GetData()->chGet() != 19) + { + rMan.Fill( c ); + DBG_ASSERT(c==21, "Ww1Fields"); + (*this)++; + c = ' '; + if (pField) + // haben wir ein fertiges feld da, das eingefuegt werden soll? + { + rOut << *pField; + delete pField; + pField = 0; + // das macht der filter so, damit attribute die ueber das feld + // gelten auch wirklich eingelesen werden und dem feld + // zugeordnet werden. + } + if (sErgebnis.Len()) + rOut << sErgebnis; + } + } +} + +enum WWDateTime{ WW_DONTKNOW = 0x0, WW_DATE = 0x1, WW_TIME = 0x2, WW_BOTH = 0x3 }; + +static WWDateTime GetTimeDatePara( const String& rForm, + SwTimeFormat* pTime = 0, + SwDateFormat* pDate = 0 ) +{ + WWDateTime eDT = WW_BOTH; + if( STRING_NOTFOUND == rForm.Search( 'H' )) // H -> 24h + { + if( pTime ) + *pTime = TF_SSMM_24; + } + else if( STRING_NOTFOUND == rForm.Search( 'H' )) // h -> 24h + { + if( pTime ) + *pTime = TF_SSMM_12; + } + else // keine Zeit + { + eDT = (WWDateTime)( eDT & ~(USHORT)WW_TIME ); + } + + xub_StrLen nDPos = 0; + while( STRING_NOTFOUND != nDPos ) + { + nDPos = rForm.Search( 'M', nDPos ); // M -> Datum + if( !nDPos ) + break; + sal_Unicode cPrev = rForm.GetChar( nDPos - 1 ); + // ignoriere dabei "AM", "aM", "PM", "pM" + if( 'a' != cPrev && 'A' != cPrev && 'p' != cPrev && 'P' != cPrev ) + break; + // else search again + ++nDPos; + } + + if( STRING_NOTFOUND != nDPos ) // Monat -> Datum ? + { + static SwDateFormat __READONLY_DATA aDateA[32] = + { + DFF_DMY, DFF_DMMY, DFF_DMYY, DFF_DMMYY, + DFF_DMMMY, DFF_DMMMY, DFF_DMMMYY, DFF_DMMMYY, + DFF_DDMMY, DFF_DDMMY, DFF_DDMMMYY, DFF_DDMMMYY, + DFF_DDMMMY, DFF_DDMMMY, DFF_DDMMMYY, DFF_DDMMMYY, + DFF_DDDMMMY, DFF_DDDMMMY, DFF_DDDMMMYY, DFF_DDDMMMYY, + DFF_DDDMMMY, DFF_DDDMMMY, DFF_DDDMMMYY, DFF_DDDMMMYY, + DFF_DDDMMMY, DFF_DDDMMMY, DFF_DDDMMMYY, DFF_DDDMMMYY, + DFF_DDDMMMY, DFF_DDDMMMY, DFF_DDDMMMYY, DFF_DDDMMMYY + }; + + BOOL bHasDay = STRING_NOTFOUND != rForm.Search( 't' ) || + STRING_NOTFOUND != rForm.Search( 'T' ) || + STRING_NOTFOUND != rForm.Search( 'd' ) || + STRING_NOTFOUND != rForm.Search( 'D' ); + + BOOL bLongDayOfWeek= STRING_NOTFOUND != rForm.SearchAscii( "tttt" ) || + STRING_NOTFOUND != rForm.SearchAscii( "TTTT" ) || + STRING_NOTFOUND != rForm.SearchAscii( "dddd" ) || + STRING_NOTFOUND != rForm.SearchAscii( "DDDD" ); + + BOOL bDayOfWeek = STRING_NOTFOUND != rForm.SearchAscii( "ttt" ) || + STRING_NOTFOUND != rForm.SearchAscii( "TTT" ) || + STRING_NOTFOUND != rForm.SearchAscii( "ddd" ) || + STRING_NOTFOUND != rForm.SearchAscii( "DDD" ); + + // M, MM -> numeric month + // MMM, MMMM -> text. month + BOOL bLitMonth = STRING_NOTFOUND != rForm.SearchAscii( "MMM" ); + // MMMM -> full month + BOOL bFullMonth = STRING_NOTFOUND != rForm.SearchAscii( "MMMM" ); + // jj, JJ -> 2-col-year + // jjjj, JJJJ -> 4-col-year + BOOL bFullYear = STRING_NOTFOUND != rForm.SearchAscii( "jjj" ) || + STRING_NOTFOUND != rForm.SearchAscii( "JJJ" ) || + STRING_NOTFOUND != rForm.SearchAscii( "yyy" ) || + STRING_NOTFOUND != rForm.SearchAscii( "YYY" ); + + USHORT i = ( bLitMonth & 1 ) + | ( ( bFullYear & 1 ) << 1 ) + | ( ( bFullMonth & 1 ) << 2 ) + | ( ( bDayOfWeek & 1 ) << 3 ) + | ( ( bLongDayOfWeek & 1 ) << 4 ); + if( pDate ) + { + if( !bHasDay && !bFullMonth ) + *pDate = DFF_MY; + else + *pDate = aDateA[i]; + } + } + else + { + eDT = (WWDateTime)( eDT & ~(USHORT)WW_DATE ); + } + return eDT; +} + + +extern void sw3io_ConvertFromOldField( SwDoc& rDoc, USHORT& rWhich, + USHORT& rSubType, ULONG &rFmt, + USHORT nVersion ); + +void Ww1Fields::Out(Ww1Shell& rOut, Ww1Manager& rMan, USHORT nDepth) +{ + String sType; // der typ als string + String sFormel; // die formel + String sFormat; + String sDTFormat; // Datum / Zeit-Format + W1_FLD* pData = GetData(); // die an den plc gebunden daten + DBG_ASSERT(pData->chGet()==19, "Ww1Fields"); // sollte beginn sein + + sal_Unicode c; + rMan.Fill( c ); + DBG_ASSERT(c==19, "Ww1Fields"); // sollte auch beginn sein + if (pData->chGet()==19 && c == 19) + { + String aStr; + c = rMan.Fill( aStr, GetLength() ); + DBG_ASSERT(Ww1PlainText::IsChar(c), "Ww1Fields"); + xub_StrLen pos = aStr.Search(' '); + // get type out of text + sType = aStr.Copy( 0, pos ); + aStr.Erase( 0, pos ); + if ( pos != STRING_NOTFOUND ) + aStr.Erase(0, 1); + sFormel += aStr; + BYTE rbType = pData->fltGet(); + do { + // solange den formelteil einlesen, bis das feld entweder + // zuende ist oder der ergebnisteil beginnt. dabei koennen + // natuerlich neue felder beginnen (word unterstuetzt felder, + // die wiederum felder beinhalten). + (*this)++; + pData = GetData(); + if (pData->chGet()==19) // nested field + { + Out(rOut, rMan, nDepth+1); + rMan.Fill(c); + DBG_ASSERT(c==21, "Ww1PlainText"); + sFormel.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "Ww" )); + sFormel += String::CreateFromInt32( nPlcIndex ); + c = rMan.Fill(aStr, GetLength()); + DBG_ASSERT(Ww1PlainText::IsChar(c), "Ww1PlainText"); + sFormel += aStr; + } + } + while (pData->chGet()==19); + + // get format out of text + pos = sFormel.SearchAscii( "\\*" ); + sFormat = sFormel.Copy( pos ); + sFormel.Erase( pos ); + + pos = sFormel.SearchAscii( "\\@" ); + sDTFormat = sFormel.Copy( pos ); + sFormel.Erase( pos ); + + // der formelteil ist zuende, kommt ein ergebnisteil? + if( pData->chGet() == 20 ) + { + rMan.Fill( c ); + DBG_ASSERT(c==20, "Ww1PlainText"); + c = rMan.Fill(sErgebnis, GetLength()); + if (!Ww1PlainText::IsChar(c)) + sErgebnis += c; //~ mdt: sonderzeichenbenhandlung + (*this)++; + pData = GetData(); + } + DBG_ASSERT(pData->chGet()==21, "Ww1PlainText"); + BOOL bKnown = TRUE; + DBG_ASSERT(pField==0, "Ww1PlainText"); + if (pField != 0) + { + rOut << *pField; + delete pField; + pField = 0; + } +// naja, aber info enthaelt alle moeglichkeiten, die auch direkt da sind +oncemore: + switch (rbType) + { + case 3: // bookmark reference + rOut.ConvertUStr( sFormel ); + pField = new SwGetRefField( (SwGetRefFieldType*) + rOut.GetSysFldType( RES_GETREFFLD ), + sFormel, + REF_BOOKMARK, + 0, + REF_CONTENT ); + + break; + case 6: // set command + { + pos = aStr.Search(' '); + String aName( aStr.Copy( 0, pos )); + aStr.Erase(0, pos ); + aStr.Erase(0, 1); + if( !aName.Len() ) + break; + rOut.ConvertUStr( aName ); + SwFieldType* pFT = rOut.GetDoc().InsertFldType( + SwSetExpFieldType( &rOut.GetDoc(), aName, nsSwGetSetExpType::GSE_STRING ) ); + pField = new SwSetExpField((SwSetExpFieldType*)pFT, aStr); + ((SwSetExpField*)pField)->SetSubType( nsSwExtendedSubType::SUB_INVISIBLE ); +// Invisible macht in 378 AErger, soll aber demnaechst gehen + + // das Ignorieren des Bookmarks ist nicht implementiert + } + break; + case 14: // info var + { + pos = aStr.Search(' '); + String aSubType( aStr.Copy( 0, pos )); + aStr.Erase(0, pos ); + aStr.Erase(0, 1); + rOut.ConvertUStr( aSubType ); + + + // ganz grosze schiete: der typ 'info' kann einem der + // typen 15..31 entsprechen. er enthaelt als formel + // das eingentliche feld der doc-info. + // kein ';' benutzen mit folgendem macro: +#define IS(sd, se, t) \ + if (aSubType.EqualsAscii( sd ) || aSubType.EqualsAscii( se)) \ + rbType = t; \ + else + + // deutsche bez. englische bez. typ-code + IS("titel", "title", 15) + IS("thema", "subject", 16) + IS("autor", "author", 17) + IS("stichw?rter", "keywords", 18) //~ mdt: umlaut + IS("kommentar", "comment", 19) + IS("gespeichertvon", "lastrevisedby", 20) + IS("ertelldat", "creationdate", 21) + IS("speicherdat", "revisiondate", 22) + IS("druckdat", "printdate", 23) + IS("version", "revisionnumber", 24) + IS("zeit", "edittime", 25) + IS("anzseit", "numberofpages", 26) + IS("anzw?rter", "numberofwords", 27) //~ mdt: umlaut + IS("anzzeichen", "numberofchars", 28) + IS("dateiname", "filename", 29) + IS("vorlage", "templatename", 30) + bKnown = FALSE; +#undef IS + if (rbType != 14) + goto oncemore; + } + break; + case 15: // title + pField = new SwDocInfoField((SwDocInfoFieldType*) + rOut.GetSysFldType(RES_DOCINFOFLD), DI_TITEL, String(), 0); + break; + case 16: // subject + pField = new SwDocInfoField((SwDocInfoFieldType*) + rOut.GetSysFldType(RES_DOCINFOFLD), DI_THEMA, String(), 0); + break; + case 17: // author + pField = new SwAuthorField((SwAuthorFieldType*) + rOut.GetSysFldType(RES_AUTHORFLD), AF_NAME ); + break; + case 18: // keywords + pField = new SwDocInfoField((SwDocInfoFieldType*) + rOut.GetSysFldType(RES_DOCINFOFLD), DI_KEYS, String(), 0); + break; + case 19: // comments + pField = new SwDocInfoField((SwDocInfoFieldType*) + rOut.GetSysFldType(RES_DOCINFOFLD), DI_COMMENT, String(), 0); + break; + case 20: // last revised by + pField = new SwDocInfoField((SwDocInfoFieldType*) + rOut.GetSysFldType(RES_DOCINFOFLD), DI_CHANGE|DI_SUB_AUTHOR, String()); + break; + case 21: // creation date + case 22: // revision date + case 23: // print date + case 25:{// edit time + USHORT nSub; + USHORT nReg = 0; // RegInfoFormat, DefaultFormat fuer DocInfoFelder + + switch( rbType ) + { + default: + case 21: nSub = DI_CREATE; nReg = DI_SUB_DATE; break; + case 23: nSub = DI_PRINT; nReg = DI_SUB_DATE; break; + case 22: nSub = DI_CHANGE; nReg = DI_SUB_DATE; break; + case 25: nSub = DI_CHANGE; nReg = DI_SUB_TIME; break; + } + switch( GetTimeDatePara( sDTFormat ) ) + { + case WW_DATE: nReg = DI_SUB_DATE; break; + case WW_TIME: nReg = DI_SUB_TIME; break; + case WW_BOTH: nReg = DI_SUB_DATE; break; + default: + break; + // WW_DONTKNOW -> Default bereits gesetzt + } + pField = new SwDocInfoField((SwDocInfoFieldType*) + rOut.GetSysFldType(RES_DOCINFOFLD), nSub | nReg, String()); + } + break; + case 24: // revision number + pField = new SwDocInfoField((SwDocInfoFieldType*) + rOut.GetSysFldType(RES_DOCINFOFLD), DI_DOCNO, String(), 0); + break; + case 26: // number of pages + pField = new SwDocStatField((SwDocStatFieldType*) + rOut.GetSysFldType(RES_DOCSTATFLD), DS_PAGE, SVX_NUM_ARABIC); + break; + case 27: // number of words + pField = new SwDocStatField((SwDocStatFieldType*) + rOut.GetSysFldType(RES_DOCSTATFLD), DS_WORD, SVX_NUM_ARABIC); + break; + case 28: // number of chars + pField = new SwDocStatField((SwDocStatFieldType*) + rOut.GetSysFldType(RES_DOCSTATFLD), DS_CHAR, SVX_NUM_ARABIC); + break; + case 29: // file name + pField = new SwFileNameField((SwFileNameFieldType*) + rOut.GetSysFldType(RES_FILENAMEFLD)); + break; + case 30: // doc template name + pField = new SwTemplNameField((SwTemplNameFieldType*) + rOut.GetSysFldType(RES_TEMPLNAMEFLD), FF_NAME); + break; + case 31: + case 32:{ + SwDateFormat aDate = DF_SSYS; + SwTimeFormat aTime = TF_SYSTEM; + + WWDateTime eDT = GetTimeDatePara(sDTFormat, &aTime, &aDate); + if( eDT == WW_DONTKNOW ) // kein D/T-Formatstring + eDT = ( rbType == 32 ) ? WW_TIME : WW_DATE; // benutze ID + + if( eDT & WW_DATE ) + { + USHORT nWhich = RES_DATEFLD; + USHORT nSubType = DATEFLD; + ULONG nFormat = aDate; + sw3io_ConvertFromOldField( rOut.GetDoc(), + nWhich, nSubType, nFormat, 0x0110 ); + pField = new SwDateTimeField((SwDateTimeFieldType*) + rOut.GetSysFldType(RES_DATETIMEFLD), DATEFLD, nFormat); + + if( eDT == WW_BOTH ) + rOut << * pField << ' '; + // Mogel: direkt einfuegen und Space dahinter + } + if( eDT & WW_TIME ) + { + USHORT nWhich = RES_TIMEFLD; + USHORT nSubType = TIMEFLD; + ULONG nFormat = aTime; + sw3io_ConvertFromOldField( rOut.GetDoc(), + nWhich, nSubType, nFormat, 0x0110 ); + pField = new SwDateTimeField((SwDateTimeFieldType*) + rOut.GetSysFldType(RES_DATETIMEFLD), TIMEFLD, nFormat); + } + + } + break; + case 33: // current page + pField = new SwPageNumberField((SwPageNumberFieldType*) + rOut.GetSysFldType(RES_PAGENUMBERFLD), PG_RANDOM, SVX_NUM_ARABIC); + break; + case 34: // evaluation exp + { + if (nDepth == 0) + { + SwGetExpFieldType* pFieldType = + (SwGetExpFieldType*)rOut.GetSysFldType(RES_GETEXPFLD); + DBG_ASSERT(pFieldType!=0, "Ww1Fields"); + if (pFieldType != 0) + pField = new SwGetExpField(pFieldType, sFormel, + nsSwGetSetExpType::GSE_STRING, VVF_SYS); + } + else // rekursion: + { + String aName( String::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM( "Ww" ))); + aName += String::CreateFromInt32( nPlcIndex ); + SwFieldType* pFT = rOut.GetDoc().GetFldType( RES_SETEXPFLD, aName, false); + if (pFT == 0) + { + SwSetExpFieldType aS(&rOut.GetDoc(), aName, nsSwGetSetExpType::GSE_FORMULA); + pFT = rOut.GetDoc().InsertFldType(aS); + } + SwSetExpField aFld((SwSetExpFieldType*)pFT, sFormel); + aFld.SetSubType(nsSwExtendedSubType::SUB_INVISIBLE); + rOut << aFld; + } + } + break; + case 36: // print command, Einfuegendatei + { + pos = aStr.Search(' '); + String aFName( aStr.Copy( 0, pos )); + aStr.Erase(0, pos ); + aStr.Erase(0, 1); + if( !aFName.Len() ) + break; + aFName.SearchAndReplaceAscii( "\\\\", String( '\\' )); + + aFName = URIHelper::SmartRel2Abs( + INetURLObject(rOut.GetBaseURL()), aFName ); + + String aName( String::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM( "WW" ))); + SwSectionData * pSection = new SwSectionData( FILE_LINK_SECTION, + rOut.GetDoc().GetUniqueSectionName( &aStr ) ); + pSection->SetLinkFileName( aFName ); + pSection->SetProtectFlag( true ); + rOut << SwFltSection( pSection ); + rOut.EndItem( RES_FLTR_SECTION ); + rOut.NextParagraph(); + } + case 37: // page ref + pField = new SwGetRefField( + (SwGetRefFieldType*)rOut.GetSysFldType(RES_GETREFFLD), + sFormel, 0, 0, REF_PAGE); + break; + case 38: // ask command + { + pos = aStr.Search(' '); + String aName( aStr.Copy( 0, pos )); + aStr.Erase(0, pos ); + aStr.Erase(0, 1); + if( !aName.Len() ) + break; + + SwFieldType* pFT = rOut.GetDoc().InsertFldType( + SwSetExpFieldType( &rOut.GetDoc(), aName, nsSwGetSetExpType::GSE_STRING ) ); + pField = new SwSetExpField((SwSetExpFieldType*)pFT, aStr ); + ((SwSetExpField*)pField)->SetInputFlag( TRUE ); + ((SwSetExpField*)pField)->SetSubType(nsSwExtendedSubType::SUB_INVISIBLE); + } + case 39: // fillin command + pField = new SwInputField( + (SwInputFieldType*)rOut.GetSysFldType( RES_INPUTFLD ), + aEmptyStr, sFormel, + INP_TXT, 0 ); // sichtbar ( geht z.Zt. nicht anders ) + break; + case 51: // macro button + { + pos = aStr.Search(' '); + String aName( aStr.Copy( 0, pos )); + aStr.Erase(0, pos ); + aStr.Erase(0, 1); + if( !aName.Len() || !aStr.Len() ) + break; + aName.InsertAscii( "StarOffice.Standard.Modul1.", 0 ); + + pField = new SwMacroField( (SwMacroFieldType*) + rOut.GetSysFldType( RES_MACROFLD ), + aName, aStr ); + } + break; + case 55: // read tiff / or better: import anything + { + const sal_Unicode* pFormel = sFormel.GetBuffer(); + const sal_Unicode* pDot = 0; + String sName; + while (*pFormel != '\0' && *pFormel != ' ') + { + // ab hier koennte eine extension kommen + if (*pFormel == '.') + pDot = pFormel; + else + // aha: wir waren bislang noch in dirs + if (*pFormel == '\\') + { + pDot = 0; + if (pFormel[1] == '\\') + pFormel++; + } + if (*pFormel != '\0') + sName += *pFormel++; + } + if( pDot ) + { + String sExt; + while( *pDot != '\0' && *pDot != ' ') + sExt += *pDot++; + + if( sExt.EqualsIgnoreCaseAscii( ".tiff" ) + || sExt.EqualsIgnoreCaseAscii( ".bmp" ) + || sExt.EqualsIgnoreCaseAscii( ".gif" ) + || sExt.EqualsIgnoreCaseAscii( ".pcx" ) + || sExt.EqualsIgnoreCaseAscii( ".pic" )) + rOut.AddGraphic( sName ); + else + bKnown = FALSE; + } + else + bKnown = FALSE; + } + break; + default: // unknown + DBG_ASSERT(FALSE, "Ww1PlainText"); + // unsupported: + case 1: // unknown + case 2: // possible bookmark + case 4: // index entry + // wwpar5: 1351/1454 + case 5: // footnote ref + case 7: // if command + case 8: // create index + // wwpar5: 1351/1454 + case 9: // table of contents entry + // wwpar5: 1351/1454 + case 10: // style ref + case 11: // doc ref + case 12: // seq ref + case 13: // create table of contents + // wwpar5: 1351/1454 + case 35: // literal text + // print merge: + case 40: // data command + case 41: // next command + case 42: // nextif command + case 43: // skipif command + case 44: // number of record + // + case 45: // dde ref + case 46: // dde auto ref + case 47: // glossary entry + case 48: // print char + case 49: // formula def + case 50: // goto button + case 52: // auto number outline + case 53: // auto number legal + case 54: // auto number arabic + bKnown = FALSE; + break; + } + if( bKnown || sErgebnis.EqualsAscii( "\270" )) + this->sErgebnis.Erase(); + else + this->sErgebnis = sErgebnis; + } + else // oops: we are terribly wrong: skip this + (*this)++; +} + +ULONG Ww1Fields::GetLength() +{ +// berechnet die laenge eines feldteiles. nicht mitgerechnet werden +// die terminierenden zeichen im text (19, 20, 21) die beginn, trenner +// und ende bedeuten. + ULONG ulBeg = Where(); + ULONG ulEnd = Where(nPlcIndex+1); + DBG_ASSERT(ulBeg<ulEnd, "Ww1Fields"); + return (ulEnd - ulBeg) - 1; +} + +/////////////////////////////////////////////////////////////////// Sep +void Ww1Sep::Start(Ww1Shell& rOut, Ww1Manager& rMan) +{ + if (rMan.Where() >= Where()) + { + rOut.NextSection(); + SwFrmFmt &rFmt = rOut.GetPageDesc().GetMaster(); + W1_DOP& rDOP = rMan.GetDop().GetDOP(); + rOut.GetPageDesc().SetLandscape(rDOP.fWideGet()); + SwFmtFrmSize aSz(rFmt.GetFrmSize()); + aSz.SetWidth(rDOP.xaPageGet()); + aSz.SetHeight(rDOP.yaPageGet()); + rFmt.SetFmtAttr(aSz); + SvxLRSpaceItem aLR(rDOP.dxaLeftGet()+rDOP.dxaGutterGet(), + rDOP.dxaRightGet(), 0, 0, RES_LR_SPACE); + rFmt.SetFmtAttr(aLR); + SvxULSpaceItem aUL(rDOP.dyaTopGet(), rDOP.dyaBottomGet(), RES_UL_SPACE); + rFmt.SetFmtAttr(aUL); + // sobald wir mit dem lesen der zeichen soweit sind, wo sep's + // momentanes attribut beginnt, wird dieses attribut eingefuegt. + // diese methode ist bei den meisten start/stop methoden der + // memberklassen des managers identisch. + BYTE* pByte = GetData(); + Ww1SprmSep aSprm(rFib, SVBT32ToUInt32(pByte + 2)); + aSprm.Start(rOut, rMan); + aSprm.Stop(rOut, rMan); + (*this)++; + aHdd.Start(rOut, rMan); + } +} + +/////////////////////////////////////////////////////////////////// Pap +void Ww1Pap::Start(Ww1Shell& rOut, Ww1Manager& rMan) +{ + if (rMan.Where() >= Where()) + { + BYTE* pByte; + USHORT cb; + // bereitstellen der zu startenden attribute + if (FillStart(pByte, cb)) + { + Ww1SprmPapx aSprm(pByte, cb); + // und ausgeben: + aSprm.Start(rOut, rMan); + } + (*this)++; + } +} + +void Ww1Pap::Stop(Ww1Shell& rOut, Ww1Manager& rMan, sal_Unicode&) +{ + if (rMan.Where() >= Where() || rMan.IsStopAll()) + { + BYTE* pByte; + USHORT cb; + if (FillStop(pByte, cb)){ + Ww1SprmPapx aSprm(pByte, cb); + aSprm.Stop(rOut, rMan); + }else{ + DBG_ASSERT( !nPlcIndex || rMan.IsStopAll(), "Pap-Attribut-Stop verloren" ); + } + } +} + +//////////////////////////////////////////////////////////////// W1_CHP +// +// momentan laesst sich die ausgabe von W1CHPxen nicht nur per define +// loesen.... +// +void W1_CHP::Out(Ww1Shell& rOut, Ww1Manager& rMan) +{ + if (fBoldGet()) + rOut << SvxWeightItem( + rOut.GetWeightBold()?WEIGHT_NORMAL:WEIGHT_BOLD, RES_CHRATR_WEIGHT); + if (fItalicGet()) + rOut << SvxPostureItem( + rOut.GetPostureItalic()?ITALIC_NONE:ITALIC_NORMAL, RES_CHRATR_POSTURE); + if (fStrikeGet()) + rOut << SvxCrossedOutItem( + rOut.GetCrossedOut()?STRIKEOUT_NONE:STRIKEOUT_SINGLE, RES_CHRATR_CROSSEDOUT); + if (fOutlineGet()) + rOut << SvxContourItem(!rOut.GetContour(), RES_CHRATR_CONTOUR); + if (fSmallCapsGet()) + rOut << SvxCaseMapItem( + rOut.GetCaseKapitaelchen()?SVX_CASEMAP_NOT_MAPPED:SVX_CASEMAP_KAPITAELCHEN, RES_CHRATR_CASEMAP); + if (fCapsGet()) + rOut << SvxCaseMapItem( + rOut.GetCaseVersalien()?SVX_CASEMAP_NOT_MAPPED:SVX_CASEMAP_VERSALIEN, RES_CHRATR_CASEMAP); + if (fsHpsGet()) + rOut << SvxFontHeightItem(hpsGet() * 10, 100, RES_CHRATR_FONTSIZE); + if (fsKulGet()) + switch (kulGet()) { + case 0: { + rOut << SvxUnderlineItem(UNDERLINE_NONE, RES_CHRATR_UNDERLINE) << + SvxWordLineModeItem(FALSE, RES_CHRATR_WORDLINEMODE); + } break; + default: DBG_ASSERT(FALSE, "Chpx"); + case 1: { + rOut << SvxUnderlineItem(UNDERLINE_SINGLE, RES_CHRATR_UNDERLINE); + } break; + case 2: { + rOut << SvxUnderlineItem(UNDERLINE_SINGLE, RES_CHRATR_UNDERLINE) << + SvxWordLineModeItem(TRUE, RES_CHRATR_WORDLINEMODE); + } break; + case 3: { + rOut << SvxUnderlineItem(UNDERLINE_DOUBLE, RES_CHRATR_UNDERLINE); + } break; + case 4: { + rOut << SvxUnderlineItem(UNDERLINE_DOTTED, RES_CHRATR_UNDERLINE); + } break; + } + + if (fsIcoGet()) + switch(icoGet()) { + default: DBG_ASSERT(FALSE, "Chpx"); + case 0: { rOut.EndItem(RES_CHRATR_COLOR); } break; + case 1: { rOut << SvxColorItem(Color(COL_BLACK), RES_CHRATR_COLOR); } break; + case 2: { rOut << SvxColorItem(Color(COL_LIGHTBLUE), RES_CHRATR_COLOR); } break; + case 3: { rOut << SvxColorItem(Color(COL_LIGHTCYAN), RES_CHRATR_COLOR); } break; + case 4: { rOut << SvxColorItem(Color(COL_LIGHTGREEN), RES_CHRATR_COLOR); } break; + case 5: { rOut << SvxColorItem(Color(COL_LIGHTMAGENTA), RES_CHRATR_COLOR); } break; + case 6: { rOut << SvxColorItem(Color(COL_LIGHTRED), RES_CHRATR_COLOR); } break; + case 7: { rOut << SvxColorItem(Color(COL_YELLOW), RES_CHRATR_COLOR); } break; + case 8: { rOut << SvxColorItem(Color(COL_WHITE), RES_CHRATR_COLOR); } break; + } + if (fsSpaceGet()) { + short sQps = qpsSpaceGet(); + if (sQps > 56) + sQps = sQps - 64; + rOut << SvxKerningItem(sQps, RES_CHRATR_KERNING); + } + if (fsPosGet()) { + if (hpsPosGet() == 0) + rOut << SvxEscapementItem(SVX_ESCAPEMENT_OFF, 100, RES_CHRATR_ESCAPEMENT); + else { + short sHps = hpsPosGet(); + if (sHps > 128) + sHps = sHps - 256; + sHps *= 100; + sHps /= 24; + rOut << SvxEscapementItem(sHps, 100, RES_CHRATR_ESCAPEMENT); + } + } + if (fsFtcGet()) { + SvxFontItem aFont(rMan.GetFont(ftcGet())); + rOut << aFont; + } +} + +/////////////////////////////////////////////////////////////////// Chp +void Ww1Chp::Start(Ww1Shell& rOut, Ww1Manager& rMan) +{ + if (rMan.Where() >= Where()) + { + W1_CHP aChpx; + if (FillStart(aChpx)) + { + aChpx.Out(rOut, rMan); + if (aChpx.fcPicGet()) + { + Ww1Picture aPic(rMan.GetFib().GetStream(), + aChpx.fcPicGet()); + if (!aPic.GetError()) + aPic.Out(rOut, rMan); + } + } + (*this)++; + } +} + +void Ww1Chp::Stop(Ww1Shell& rOut, Ww1Manager& rMan, sal_Unicode&) +{ + if (rMan.Where() >= Where()) + { + W1_CHP aChpx; + if (FillStop(aChpx)) + { + // zuerst alle toggle-flags + if (aChpx.fBoldGet()) + rOut.EndItem(RES_CHRATR_WEIGHT); + if (aChpx.fItalicGet()) + rOut.EndItem(RES_CHRATR_POSTURE); + if (aChpx.fStrikeGet()) + rOut.EndItem(RES_CHRATR_CROSSEDOUT); + if (aChpx.fOutlineGet()) + rOut.EndItem(RES_CHRATR_CONTOUR); + if (aChpx.fSmallCapsGet() || aChpx.fCapsGet()) + rOut.EndItem(RES_CHRATR_CASEMAP); + // dann alle zahl-werte, diese haben flags, wenn sie gesetzt + // sind.................. + if (aChpx.fsHpsGet()) + rOut.EndItem(RES_CHRATR_FONTSIZE); + if (aChpx.fsKulGet()) + rOut.EndItem(RES_CHRATR_UNDERLINE) + .EndItem(RES_CHRATR_WORDLINEMODE); + if (aChpx.fsIcoGet()) + rOut.EndItem(RES_CHRATR_COLOR); + if (aChpx.fsSpaceGet()) + rOut.EndItem(RES_CHRATR_KERNING); + if (aChpx.fsPosGet()) + rOut.EndItem(RES_CHRATR_ESCAPEMENT); + if (aChpx.fsFtcGet()) + rOut.EndItem(RES_CHRATR_FONT); + }else{ + DBG_ASSERT( !nPlcIndex, "Chp-Attribut-Stop verloren" ); + } + } +} + +///////////////////////////////////////////////////////////////// Style +void Ww1Style::Out(Ww1Shell& rOut, Ww1Manager& rMan) +{ +// Zuerst Basis, damit Attribute des Basis-Styles erkannt werden +// first: Base................................................ + if(pParent->GetStyle(stcBase).IsUsed() ) // Basis gueltig ? + rOut.BaseStyle(stcBase); + +// next of all: CHP............................................... + aChpx.Out(rOut, rMan); +// Last: PAP....................................................... + if (pPapx) + pPapx->Start(rOut, rMan); +} + +////////////////////////////////////////////////////////// Ww1PlainText +// +// die Out() methoden von plaintext fuer den filter geben eine anzahl +// zeichen aus auf die shell, einen string oder einen char, wieviel +// zeichen ausgegeben werden, bestimmt ulEnd, das das ende bestimmt, +// bis zudem ausgegeben wird. ausserdem beenden die methoden die +// ausgabe bei kontrollzeichen. +// diese sind definiert durch MinChar. alle zeichen mit wert darunter +// gelten als kontroll- zeichen. dafuer gibts die methode IsChar, die +// zurueckgibt, ob es sich um ein standard zeichen handelt. kommt ein +// solches zeichen, wird dieses zeichen zurueckgegeben und die methode +// beendet, auch wenn ulEnd noch nicht erreicht wurde. bei nutzung +// also beachten, dasz wenn !IsChar(Out(...)) gilt, ulEnd unter +// umstaenden nicht erreicht wurde. dann wurde das kontrollzeichen +// zwar (weg-)gelesen, jedoch noch nicht ausgegeben. +// +sal_Unicode Ww1PlainText::Out( Ww1Shell& rOut, ULONG& ulEnd ) +{ +// gibt die zeichen bis ulEnd aus, es sei den es kommen sonderzeichen +// die eine bedeutung haben wie absatzende oder seitenumbruch. + if (ulEnd > Count()) + ulEnd = Count(); + while (ulSeek < ulEnd) + { + sal_Unicode c = (*this)[ulSeek]; + (*this)++; + if (Ww1PlainText::IsChar(c)) + rOut << c; + else + return c; + } + return Ww1PlainText::MinChar; +} + +sal_Unicode Ww1PlainText::Out( String& rStr, ULONG ulEnd ) +{ +// wie Out(Shell..., jedoch ausgabe auf einen string + rStr.Erase(); + if (ulEnd > Count()) + ulEnd = Count(); + while (ulSeek < ulEnd) + { + sal_Unicode c = (*this)[ulSeek]; + (*this)++; + if( Ww1PlainText::IsChar(c) ) + rStr += c; + else + return c; + } + return Ww1PlainText::MinChar; +} + +// +// hier eruebrigt sich ulEnd...oder? +// +sal_Unicode Ww1PlainText::Out( sal_Unicode& rRead ) +{ + rRead = (*this)[ulSeek]; + (*this)++; + return rRead; +} + +/////////////////////////////////////////////////////////// Ww1SprmPapx + +void Ww1SprmPapx::Start(Ww1Shell& rOut, Ww1Manager& rMan) +{ + if( !rMan.IsInStyle() ){ // Innerhalb Style gehts ueber die + // normalen Attribute + if (!rOut.IsInFly() + && !rOut.IsInTable() // Nicht innerhalb Tabelle! + && ( rMan.HasPPc() || rMan.HasPDxaAbs())){ // Fly-Start + rOut.BeginFly(); // eAnchor ); + } + if (!rOut.IsInTable() && rMan.HasInTable()) + { + rOut.BeginTable(); + } + rOut.SetStyle(aPapx.stcGet()); + } + Ww1Sprm::Start(rOut, rMan); +} + +void Ww1SprmPapx::Stop(Ww1Shell& rOut, Ww1Manager& rMan) +{ + Ww1Sprm::Stop(rOut, rMan); + + if( !rMan.IsInStyle() ) // Innerhalb Style gehts ueber die + { // normalen Attribute + if (rOut.IsInTable() &&( rMan.IsStopAll() || !rMan.HasInTable())) + rOut.EndTable(); + + if( rOut.IsInFly() && + ( rMan.IsStopAll() + || ( !rMan.HasPPc() && !rMan.HasPDxaAbs() // Fly-Ende + && !rOut.IsInTable()))) // Nicht innerhalb Tabelle! + rOut.EndFly(); + } +} + +///////////////////////////////////////////////////////////////// Fonts +SvxFontItem Ww1Fonts::GetFont(USHORT nFCode) +{ +// erzeugen eine fonts im sw-sinne aus den word-strukturen + FontFamily eFamily = FAMILY_DONTKNOW; + String aName; + FontPitch ePitch = PITCH_DONTKNOW; + rtl_TextEncoding eCharSet = RTL_TEXTENCODING_DONTKNOW; + switch (nFCode) + { +// In the Winword 1.x format, the names of the first three fonts were +// omitted from the table and assumed to be "Tms Rmn" (for ftc = 0), +// "Symbol", and "Helv" + case 0: + eFamily = FAMILY_ROMAN; + aName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Tms Rmn" )); + ePitch = PITCH_VARIABLE; + eCharSet = RTL_TEXTENCODING_MS_1252; + break; + case 1: + aName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Symbol" )); + ePitch = PITCH_VARIABLE; + eCharSet = RTL_TEXTENCODING_SYMBOL; + break; + case 2: + eFamily = FAMILY_SWISS; + aName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Helv" )); + ePitch = PITCH_VARIABLE; + eCharSet = RTL_TEXTENCODING_MS_1252; + break; + default: + { + W1_FFN* pF = GetFFN(nFCode - 3); + if (pF != 0) + { + // Fontname ......................................... + aName = String( (sal_Char*)pF->szFfnGet(), + RTL_TEXTENCODING_MS_1252 ); + // Pitch ............................................. + static FontPitch ePitchA[] = + { + PITCH_DONTKNOW, PITCH_FIXED, PITCH_VARIABLE, PITCH_DONTKNOW + }; + ePitch = ePitchA[pF->prgGet()]; + // CharSet ........................................... + eCharSet = RTL_TEXTENCODING_MS_1252; + if (aName.EqualsIgnoreCaseAscii("Symbol") + || aName.EqualsIgnoreCaseAscii("Symbol Set") + || aName.EqualsIgnoreCaseAscii("Wingdings") + || aName.EqualsIgnoreCaseAscii("ITC Zapf Dingbats") ) + eCharSet = RTL_TEXTENCODING_SYMBOL; + // FontFamily ........................................ + USHORT b = pF->ffGet(); + static FontFamily eFamilyA[] = + { + FAMILY_DONTKNOW, FAMILY_ROMAN, FAMILY_SWISS, FAMILY_MODERN, + FAMILY_SCRIPT, FAMILY_DECORATIVE + }; + if (b < sizeof(eFamilyA)) + eFamily = eFamilyA[b]; + } + else + { + DBG_ASSERT(FALSE, "WW1Fonts::GetFont: Nicht existenter Font !"); + eFamily = FAMILY_SWISS; + aName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Helv" )); + ePitch = PITCH_VARIABLE; + eCharSet = RTL_TEXTENCODING_MS_1252; + } + } + break; + } + // Extrawurst Hypo + if ( SwFltGetFlag( nFieldFlags, SwFltControlStack::HYPO ) + && ( aName.EqualsIgnoreCaseAscii("Helv") + || aName.EqualsIgnoreCaseAscii("Helvetica") ) ) + { + aName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Helvetica Neue" )); + if (eFamily==FAMILY_DONTKNOW) + eFamily = FAMILY_SWISS; + } + else + { + // VCL matcht die Fonts selber + // allerdings passiert bei Helv, Tms Rmn und System Monospaced + // Scheisse, so dass diese ersetzt werden muessen. + // Nach TH sollen diese durch feste Werte ersetzt werden, + // also nicht ueber System::GetStandardFont, damit keine + // Namenslisten auftauchen ( Dieses koennte den User verwirren ) + if( aName.EqualsIgnoreCaseAscii("Helv")) + { + aName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Helvetica" )); + if (eFamily==FAMILY_DONTKNOW) + eFamily = FAMILY_SWISS; + } + else if (aName.EqualsIgnoreCaseAscii("Tms Rmn")) + { + aName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Times New Roman" )); + if (eFamily==FAMILY_DONTKNOW) + eFamily = FAMILY_ROMAN; + } + else if (aName.EqualsIgnoreCaseAscii("System Monospaced") ) + { + aName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Courier" )); + ePitch = PITCH_FIXED; + } + } +// nun koennen wir den font basteln: ......................... + return SvxFontItem(eFamily, aName, aEmptyStr, ePitch, eCharSet, RES_CHRATR_FONT); +} + +/////////////////////////////////////////////////////////////////// Dop +void Ww1Dop::Out(Ww1Shell& rOut) +{ + //~ mdt: fehlt + long nDefTabSiz = aDop.dxaTabGet(); + if (nDefTabSiz < 56) + nDefTabSiz = 709; + + // wir wollen genau einen DefaultTab + SvxTabStopItem aNewTab(1, USHORT(nDefTabSiz), SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP); + ((SvxTabStop&)aNewTab[0]).GetAdjustment() = SVX_TAB_ADJUST_DEFAULT; + rOut.GetDoc().GetAttrPool().SetPoolDefaultItem( aNewTab); //~ mdt: besser (GetDoc) + + SwFrmFmt &rFmt = rOut.GetPageDesc().GetMaster(); + W1_DOP& rDOP = GetDOP(); + rOut.GetPageDesc().SetLandscape(rDOP.fWideGet()); + SwFmtFrmSize aSz(rFmt.GetFrmSize()); + aSz.SetWidth(rDOP.xaPageGet()); + aSz.SetHeight(rDOP.yaPageGet()); + rFmt.SetFmtAttr(aSz); + SvxLRSpaceItem aLR(rDOP.dxaLeftGet()+rDOP.dxaGutterGet(), + rDOP.dxaRightGet(), 0, 0, RES_LR_SPACE); + rFmt.SetFmtAttr(aLR); + SvxULSpaceItem aUL(rDOP.dyaTopGet(), rDOP.dyaBottomGet(), RES_UL_SPACE); + rFmt.SetFmtAttr(aUL); + + SwFtnInfo aInfo; + aInfo = rOut.GetDoc().GetFtnInfo(); // Copy-Ctor privat + // wo positioniert ? ( 0 == Section, 1 == Page, + // 2 == beim Text -> Page, 3 == Doc ) + switch( rDOP.fpcGet() ){ + case 1: + case 2: aInfo.ePos = FTNPOS_PAGE; break; + default: aInfo.ePos = FTNPOS_CHAPTER; break; + } + // Da Sw unter Chapter anscheinend was anderes versteht als PMW + // hier also immer Doc ! + aInfo.eNum = FTNNUM_DOC; + // wie neu nummerieren ? + // SW-UI erlaubt Nummer nur bei FTNNUM_DOC + if( rDOP.nFtnGet() > 0 && aInfo.eNum == FTNNUM_DOC ) + aInfo.nFtnOffset = rDOP.nFtnGet() - 1; + rOut.GetDoc().SetFtnInfo( aInfo ); + +} + +///////////////////////////////////////////////////////////////// Assoc +void Ww1Assoc::Out(Ww1Shell& rOut) +{ +//~ mdt: fehlen: FileNext, Dot, DataDoc, HeaderDoc, Criteria1, +// Criteria2, Criteria3, Criteria4, Criteria5, Criteria6, Criteria7 + SwDocShell *pDocShell(rOut.GetDoc().GetDocShell()); + DBG_ASSERT(pDocShell, "no SwDocShell"); + if (pDocShell) { + uno::Reference<document::XDocumentPropertiesSupplier> xDPS( + pDocShell->GetModel(), uno::UNO_QUERY_THROW); + uno::Reference<document::XDocumentProperties> xDocProps( + xDPS->getDocumentProperties()); + DBG_ASSERT(xDocProps.is(), "DocumentProperties is null"); + if (xDocProps.is()) { + xDocProps->setTitle( GetStr(Title) ); + xDocProps->setSubject( GetStr(Subject) ); + xDocProps->setDescription( GetStr(Comments) ); + xDocProps->setKeywords( + ::comphelper::string::convertCommaSeparated( GetStr(KeyWords) ) ); + xDocProps->setAuthor( GetStr(Author) ); + xDocProps->setModifiedBy( GetStr(LastRevBy) ); + } + } +} + +//////////////////////////////////////////////////////////// StyleSheet +void Ww1StyleSheet::OutDefaults(Ww1Shell& rOut, Ww1Manager& rMan, USHORT stc) +{ + switch (stc){ + case 222: // Null + rOut << SvxFontHeightItem(240, 100, RES_CHRATR_FONTSIZE); + rOut << SvxFontItem(rMan.GetFont(2)); + break; + case 223: // annotation reference + rOut << SvxFontHeightItem(160, 100, RES_CHRATR_FONTSIZE); + break; + case 224: // annotation text + rOut << SvxFontHeightItem(200, 100, RES_CHRATR_FONTSIZE); + break; + case 225: // table of contents 8 + case 226: // table of contents 7 + case 227: // table of contents 6 + case 228: // table of contents 5 + case 229: // table of contents 4 + case 230: // table of contents 3 + case 231: // table of contents 2 + case 232: // table of contents 1 + rOut << SvxLRSpaceItem(( 232 - stc ) * 720, 720, 0, 0, RES_LR_SPACE); + // Tabulatoren fehlen noch ! + break; + case 233: // index 7 + case 234: // und index 6 + case 235: // und index 5 + case 236: // und index 4 + case 237: // und index 3 + case 238: // und index 2 + rOut << SvxLRSpaceItem(( 239 - stc ) * 360, 0, 0, 0, RES_LR_SPACE); + break; + case 239: // index 1 + break; + case 240: // line number + break; + case 241: // index heading + break; + case 242: // footer + case 243:{ // ... und header + SvxTabStopItem aAttr(RES_PARATR_TABSTOP); + SvxTabStop aTabStop; + aTabStop.GetTabPos() = 4535; // 8 cm + aTabStop.GetAdjustment() = SVX_TAB_ADJUST_CENTER; + aAttr.Insert( aTabStop ); + aTabStop.GetTabPos() = 9071; // 16 cm + aTabStop.GetAdjustment() = SVX_TAB_ADJUST_RIGHT; + aAttr.Insert( aTabStop ); + rOut << aAttr; + } + break; + case 244: // footnote reference + rOut << SvxFontHeightItem(160, 100, RES_CHRATR_FONTSIZE); + rOut << SvxEscapementItem(6 * 100 / 24, 100, RES_CHRATR_ESCAPEMENT); + break; + case 245: // footnote text + rOut << SvxFontHeightItem(200, 100, RES_CHRATR_FONTSIZE); + break; + case 246: // heading 9 + case 247: // und heading 8 + case 248: // und heading 7 + rOut << SvxLRSpaceItem(720, 0, 0, 0, RES_LR_SPACE); + rOut << SvxPostureItem( + rOut.GetPostureItalic()?ITALIC_NONE:ITALIC_NORMAL, RES_CHRATR_POSTURE); + rOut << SvxFontHeightItem(200, 100, RES_CHRATR_FONTSIZE); + break; + case 249: // heading 6 + rOut << SvxLRSpaceItem(720, 0, 0, 0, RES_LR_SPACE); + rOut << SvxUnderlineItem(UNDERLINE_SINGLE, RES_CHRATR_UNDERLINE); + rOut << SvxFontHeightItem(200, 100, RES_CHRATR_FONTSIZE); + break; + case 250: // heading 5 + rOut << SvxLRSpaceItem(720, 0, 0, 0, RES_LR_SPACE); + rOut << SvxWeightItem(rOut.GetWeightBold()?WEIGHT_NORMAL:WEIGHT_BOLD, RES_CHRATR_WEIGHT); + rOut << SvxFontHeightItem(200, 100, RES_CHRATR_FONTSIZE); + break; + case 251: // heading 4 + rOut << SvxLRSpaceItem(360, 0, 0, 0, RES_LR_SPACE); + rOut << SvxUnderlineItem(UNDERLINE_SINGLE, RES_CHRATR_UNDERLINE); + rOut << SvxFontHeightItem(240, 100, RES_CHRATR_FONTSIZE); + break; + case 252: // heading 3 + rOut << SvxLRSpaceItem(360, 0, 0, 0, RES_LR_SPACE); + rOut << SvxWeightItem(rOut.GetWeightBold()?WEIGHT_NORMAL:WEIGHT_BOLD, RES_CHRATR_WEIGHT); + rOut << SvxFontHeightItem(240, 100, RES_CHRATR_FONTSIZE); + break; + case 253: // heading 2 + rOut << SvxULSpaceItem(120, 0, RES_UL_SPACE); + rOut << SvxWeightItem(rOut.GetWeightBold()?WEIGHT_NORMAL:WEIGHT_BOLD, RES_CHRATR_WEIGHT); + rOut << SvxFontHeightItem(240, 100, RES_CHRATR_FONTSIZE); + rOut << SvxFontItem(rMan.GetFont(2)); + break; + case 254: // heading 1 + rOut << SvxULSpaceItem(240, 0, RES_UL_SPACE); + rOut << SvxWeightItem(rOut.GetWeightBold()?WEIGHT_NORMAL:WEIGHT_BOLD, RES_CHRATR_WEIGHT); + rOut << SvxUnderlineItem(UNDERLINE_SINGLE, RES_CHRATR_UNDERLINE); + rOut << SvxFontHeightItem(240, 100, RES_CHRATR_FONTSIZE); + rOut << SvxFontItem(rMan.GetFont(2)); + break; + case 255: // Normal indent + rOut << SvxLRSpaceItem(720, 0, 0, 0, RES_LR_SPACE); + break; + case 0: // Normal + rOut << SvxFontHeightItem(200, 100, RES_CHRATR_FONTSIZE); + break; + default: // selbstdefiniert + rOut << SvxFontHeightItem(200, 100, RES_CHRATR_FONTSIZE); + break; + } +} + +void Ww1StyleSheet::OutOne(Ww1Shell& rOut, Ww1Manager& rMan, USHORT stc) +{ + const RES_POOL_COLLFMT_TYPE RES_NONE = RES_POOLCOLL_DOC_END; + RES_POOL_COLLFMT_TYPE aType = RES_NONE; + + switch (stc) + { + case 222: // Null + aType = RES_POOLCOLL_TEXT; break; //??? + case 223: // annotation reference + break; + case 224: // annotation text + break; + case 225: // table of contents 8 + aType = RES_POOLCOLL_TOX_CNTNT8; break; + case 226: // table of contents 7 + aType = RES_POOLCOLL_TOX_CNTNT7; break; + case 227: // table of contents 6 + aType = RES_POOLCOLL_TOX_CNTNT6; break; + case 228: // table of contents 5 + aType = RES_POOLCOLL_TOX_CNTNT5; break; + case 229: // table of contents 4 + aType = RES_POOLCOLL_TOX_CNTNT4; break; + case 230: // table of contents 3 + aType = RES_POOLCOLL_TOX_CNTNT3; break; + case 231: // table of contents 2 + aType = RES_POOLCOLL_TOX_CNTNT2; break; + case 232: // table of contents 1 + aType = RES_POOLCOLL_TOX_CNTNT1; break; + case 233: // index 7 + break; + case 234: // index 6 + break; + case 235: // index 5 + break; + case 236: // index 4 + break; + case 237: // index 3 + aType = RES_POOLCOLL_TOX_IDX3; break; + case 238: // index 2 + aType = RES_POOLCOLL_TOX_IDX2; break; + case 239: // index 1 + aType = RES_POOLCOLL_TOX_IDX1; break; + case 240: // line number + break; + case 241: // index heading + break; + case 242: // footer + aType = RES_POOLCOLL_FOOTER; break; + case 243: // header + aType = RES_POOLCOLL_HEADER; break; + case 244: // footnote reference + break; + case 245: // footnote text + aType = RES_POOLCOLL_FOOTNOTE; break; + case 246: // heading 9 + break; + case 247: // heading 8 + break; + case 248: // heading 7 + break; + case 249: // heading 6 + break; + case 250: // heading 5 + aType = RES_POOLCOLL_HEADLINE5; break; + case 251: // heading 4 + aType = RES_POOLCOLL_HEADLINE4; break; + case 252: // heading 3 + aType = RES_POOLCOLL_HEADLINE3; break; + case 253: // heading 2 + aType = RES_POOLCOLL_HEADLINE2; break; + case 254: // heading 1 + aType = RES_POOLCOLL_HEADLINE1; break; + case 255: // Normal indent + aType = RES_POOLCOLL_TEXT_IDENT; break; + case 0: // Normal + aType = RES_POOLCOLL_STANDARD; break; + } + if (aType == RES_NONE) + rOut.BeginStyle(stc, GetStyle(stc).GetName() ); + else + rOut.BeginStyle(stc, aType); + OutDefaults(rOut, rMan, stc); + GetStyle(stc).Out(rOut, rMan); + rOut.EndStyle(); +} +// OutOneWithBase() liest einen Style mit OutOne() einen Style ein +// Jedoch liest er, wenn noch nicht geschehen, den Basisstyle rekursiv ein +void Ww1StyleSheet::OutOneWithBase(Ww1Shell& rOut, Ww1Manager& rMan, + USHORT stc, BYTE* pbStopRecur ) +{ +// SH: lineares Einlesen ist Scheisse, da dann BasedOn nicht gesetzt +// werden kann und ausserdem Toggle- und Modify-Attrs (z.B. Tabs ) nicht gehen. + + Ww1Style& rSty = GetStyle(stc); + USHORT nBase = rSty.GetnBase(); + if( nBase != stc + && !rOut.IsStyleImported( nBase ) + && GetStyle(nBase).IsUsed() + && !pbStopRecur[nBase] ){ + + pbStopRecur[nBase] = 1; + OutOneWithBase( rOut, rMan, nBase, pbStopRecur ); // Rekursiv + } + OutOne( rOut, rMan, stc ); +} + +void Ww1StyleSheet::Out(Ww1Shell& rOut, Ww1Manager& rMan) +{ + USHORT stc; + BYTE bStopRecur[256]; + memset( bStopRecur, FALSE, sizeof(bStopRecur) ); + +// 1. Durchlauf: Styles mit Basisstyles rekursiv + for (stc=0;stc<Count();stc++) + if (GetStyle(stc).IsUsed() && !rOut.IsStyleImported( stc ) ) + OutOneWithBase( rOut, rMan, stc, bStopRecur ); + +// 2. Durchlauf: Follow-Styles + for (stc=0;stc<Count();stc++){ + Ww1Style& rSty = GetStyle(stc); + if ( rSty.IsUsed() ){ + USHORT nNext = rSty.GetnNext(); + if( nNext != stc && GetStyle(nNext).IsUsed() ) + rOut.NextStyle( stc, nNext ); + } + } +} + +////////////////////////////////////////////////////////////// Picture +static ULONG GuessPicSize(W1_PIC* pPic) +{ + USHORT maxx = pPic->mfp.xExtGet(); + USHORT padx = ((maxx + 7) / 8) * 8; + USHORT maxy = pPic->mfp.yExtGet(); + return 120L + (ULONG)padx * maxy; +} + +// +// folgende methode schreibt eine windows-.BMP-datei aus einem +// embeddeten bild in ww-1 dateien +// gelesen wird 4-bit format, geschrieben jedoch 8-bit. +// +void Ww1Picture::WriteBmp(SvStream& rOut) +{ + long nSize = pPic->lcbGet() - (sizeof(*pPic)-sizeof(pPic->rgb)); + BYTE* p = pPic->rgbGet(); + USHORT maxx = pPic->mfp.xExtGet(); + USHORT padx = ((maxx + 7) / 8) * 8; + USHORT maxy = pPic->mfp.yExtGet(); + + p+= sizeof(SVBT16); nSize -= sizeof(SVBT16); + p+= sizeof(SVBT16); nSize -= sizeof(SVBT16); +#if OSL_DEBUG_LEVEL > 1 + USHORT x = SVBT16ToShort(p); + (void) x; +#endif + p+= sizeof(SVBT16); nSize -= sizeof(SVBT16); +#if OSL_DEBUG_LEVEL > 1 + USHORT y = SVBT16ToShort(p); + (void) y; +#endif + p+= sizeof(SVBT16); nSize -= sizeof(SVBT16); +#if OSL_DEBUG_LEVEL > 1 + USHORT planes = SVBT16ToShort(p); + (void) planes; +#endif + p+= sizeof(SVBT16); nSize -= sizeof(SVBT16); +#if OSL_DEBUG_LEVEL > 1 + USHORT bitcount = SVBT16ToShort(p); + (void) bitcount; +#endif + p+= sizeof(SVBT16); nSize -= sizeof(SVBT16); + +#if OSL_DEBUG_LEVEL > 1 + DBG_ASSERT(x==maxx, "Ww1Picture"); + DBG_ASSERT(y==maxy, "Ww1Picture"); + DBG_ASSERT(planes==1, "Ww1Picture"); + DBG_ASSERT(bitcount==4, "Ww1Picture"); +#endif + + DBG_ASSERT(16*3+padx*maxy/2==nSize, "Ww1Picture"); + + SVBT32 tmpLong; + SVBT16 tmpShort; + SVBT8 tmpByte; +#define wLong(n) \ + UInt32ToSVBT32(n, tmpLong); \ + if ((rOut.Write(tmpLong, sizeof(SVBT32))) != sizeof(SVBT32)) goto error; +#define wShort(n) \ + ShortToSVBT16(n, tmpShort); \ + if ((rOut.Write(tmpShort, sizeof(SVBT16))) != sizeof(SVBT16)) goto error; +#define wByte(n) \ + ByteToSVBT8(n, tmpByte); \ + if ((rOut.Write(tmpByte, sizeof(SVBT8))) != sizeof(SVBT8)) goto error; + wByte('B'); wByte('M'); + wLong(54 + 4 * 16 + padx * maxy); + wLong(0); + wLong(54 + 4 * 16); + wLong(40); + wLong(maxx); + wLong(maxy); + wShort(1); + wShort(8); + wLong(0); + wLong(0); + wLong(0); + wLong(0); + wLong(16); + wLong(16); + USHORT i; + for (i=0;nSize>0&&i<16;i++) + { + wByte(*p); + p++; + nSize -= sizeof(BYTE); + wByte(*p); + p++; + nSize -= sizeof(BYTE); + wByte(*p); + p++; + nSize -= sizeof(BYTE); + wByte(0); + } + DBG_ASSERT(padx*maxy/2==nSize, "Ww1Picture"); + USHORT j; +#if 1 + { + BYTE* pBuf = new BYTE[padx]; + for (j=0;nSize>0&&j<maxy;j++) + { + BYTE* q = pBuf; + for (i=0;nSize>0&&i<maxx;i+=2) + { + *q++ = *p>>4; + *q++ = *p&0xf; + p++; + nSize -= sizeof(BYTE); + } + for (;i<padx;i+=2) + { + *q++ = 0; + p++; + nSize -= sizeof(BYTE); + } + if(rOut.Write(pBuf, padx) != padx){ + delete [] pBuf; + goto error; + } + } + delete [] pBuf; + } +#else + for (j=0;nSize>0&&j<maxy;j++) + { + for (i=0;nSize>0&&i<maxx;i+=2) + { + wByte(*p>>4); + wByte(*p&0xf); + p++; + nSize -= sizeof(BYTE); + } + for (;i<padx;i+=2) + { + wByte(0); + p++; + nSize -= sizeof(BYTE); + } + } +#endif + DBG_ASSERT(nSize==0, "Ww1Picture"); +#undef wLong +#undef wShort +#undef wByte + rOut.Seek(0); + return; +error: + ; +} + +void Ww1Picture::Out(Ww1Shell& rOut, Ww1Manager& /*rMan*/) +{ + Graphic* pGraphic = 0; + USHORT mm; + switch (mm = pPic->mfp.mmGet()) + { + case 8: // embedded metafile + { + SvMemoryStream aOut(8192, 8192); + aOut.Write(pPic->rgbGet(), pPic->lcbGet() - + (sizeof(*pPic)-sizeof(pPic->rgb))); + aOut.Seek(0); + GDIMetaFile aWMF; + if (ReadWindowMetafile( aOut, aWMF, NULL ) && aWMF.GetActionCount() > 0) + { + aWMF.SetPrefMapMode(MapMode(MAP_100TH_MM)); + Size aOldSiz(aWMF.GetPrefSize()); + Size aNewSiz(pPic->mfp.xExtGet(), pPic->mfp.yExtGet()); + Fraction aFracX(aNewSiz.Width(), aOldSiz.Width()); + Fraction aFracY(aNewSiz.Height(), aOldSiz.Height()); + aWMF.Scale(aFracX, aFracY); + aWMF.SetPrefSize(aNewSiz); + pGraphic = new Graphic(aWMF); + } + break; + } + case 94: // embedded name SH:??? Was denn nun ? Embeddet oder Name ? + case 98: // TIFF-Name + { + String aDir( (sal_Char*)pPic->rgbGet(), + (USHORT)(pPic->lcbGet() - (sizeof(*pPic)-sizeof(pPic->rgb))), + RTL_TEXTENCODING_MS_1252 ); + + rOut.AddGraphic( aDir ); + } + break; + case 97: // embedded bitmap + { + ULONG nSiz = GuessPicSize(pPic); + SvMemoryStream aOut(nSiz, 8192); + WriteBmp(aOut); + Bitmap aBmp; + aOut >> aBmp; + pGraphic = new Graphic(aBmp); + } + default: + DBG_ASSERT(pPic->mfp.mmGet() == 97, "Ww1Picture"); + } + if (pGraphic) + rOut << *pGraphic; +} + +////////////////////////////////////////////////////////// HeaderFooter +void Ww1HeaderFooter::Start(Ww1Shell& rOut, Ww1Manager& rMan) +{ +// wird sowieso nur bei SEPs aufgerufen, keine weitere pruefung +// noetig: + if (!rMan.Pushed()) + { + while ((*this)++) + switch (eHeaderFooterMode) + { + case FtnSep: + break; + case FtnFollowSep: + break; + case FtnNote: + break; + case EvenHeadL: + break; + case OddHeadL: + { + ULONG begin = 0; + ULONG end = 0; + if (FillOddHeadL(begin, end)) + { + Ww1HddText* pText = new Ww1HddText(rMan.GetFib()); + pText->Seek(begin); + pText->SetCount(end-begin); + rOut.BeginHeader(); + rMan.Push1(pText, pText->Offset(rMan.GetFib()), begin, + new Ww1HeaderFooterFields(rMan.GetFib())); + rOut << rMan; + rMan.Pop(); + rOut.EndHeaderFooter(); + return; + } + } + break; + case EvenFootL: + break; + case OddFootL: + { + ULONG begin = 0; + ULONG end = 0; + if (FillOddFootL(begin, end)) + { + Ww1HddText* pText = new Ww1HddText(rMan.GetFib()); + pText->Seek(begin); + pText->SetCount(end-begin); + rOut.BeginFooter(); + rMan.Push1(pText, pText->Offset(rMan.GetFib()), begin, + new Ww1HeaderFooterFields(rMan.GetFib())); + rOut << rMan; + rMan.Pop(); + rOut.EndHeaderFooter(); + return; + } + } + break; + case FirstHeadL: + break; + default: + break; + } + } +} + +void Ww1HeaderFooter::Stop(Ww1Shell& rOut, Ww1Manager& rMan, sal_Unicode&) +{ + if (!rMan.Pushed() && eHeaderFooterMode != None) + { + Start(rOut, rMan); + } +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww1/w1par.cxx b/sw/source/filter/ww1/w1par.cxx new file mode 100644 index 000000000000..c90e39b173a7 --- /dev/null +++ b/sw/source/filter/ww1/w1par.cxx @@ -0,0 +1,139 @@ +/* -*- 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +#include <pam.hxx> // fuer SwPam +#include <doc.hxx> +#include <ndtxt.hxx> // class SwTxtNode +#include <fltini.hxx> // Ww1Reader +#include <w1par.hxx> +#include <swfltopt.hxx> +#include <mdiexp.hxx> // StatLine...() +#include <swerror.h> // ERR_WW1_... +#include <statstr.hrc> // ResId fuer Statusleiste + +//---------------------------------------- +// Initialisieren der Feld-FilterFlags +//---------------------------------------- + +static ULONG WW1_Read_FieldIniFlags() +{ +// USHORT i; + static const sal_Char* aNames[ 1 ] = { "WinWord/WW1F" }; + sal_uInt32 aVal[ 1 ]; + SwFilterOptions aOpt( 1, aNames, aVal ); + ULONG nFieldFlags = aVal[ 0 ]; + + if ( SwFltGetFlag( nFieldFlags, SwFltControlStack::HYPO ) ) + { + SwFltSetFlag( nFieldFlags, SwFltControlStack::BOOK_TO_VAR_REF ); + SwFltSetFlag( nFieldFlags, SwFltControlStack::TAGS_DO_ID ); + SwFltSetFlag( nFieldFlags, SwFltControlStack::TAGS_IN_TEXT ); + SwFltSetFlag( nFieldFlags, SwFltControlStack::ALLOW_FLD_CR ); + } + return nFieldFlags; +} + +////////////////////////////////////////////////// StarWriter-Interface +// +// Eine Methode liefern die call-Schnittstelle fuer den Writer. +// Read() liest eine Datei. hierzu werden zwei Objekte erzeugt, die Shell, +// die die Informationen aufnimmt und der Manager der sie aus der Datei liest. +// Diese werden dann einfach per Pipe 'uebertragen'. +// + +ULONG WW1Reader::Read(SwDoc& rDoc, const String& rBaseURL, SwPaM& rPam, const String& /*cName*/) +{ + ULONG nRet = ERR_SWG_READ_ERROR; + OSL_ENSURE(pStrm!=NULL, "W1-Read ohne Stream"); + if (pStrm != NULL) + { + BOOL bNew = !bInsertMode; // Neues Doc ( kein Einfuegen ) + + // erstmal eine shell konstruieren: die ist schnittstelle + // zum writer-dokument + ULONG nFieldFlags = WW1_Read_FieldIniFlags(); + Ww1Shell* pRdr = new Ww1Shell( rDoc, rPam, rBaseURL, bNew, nFieldFlags ); + if( pRdr ) + { + // dann den manager, der liest die struktur des word-streams + Ww1Manager* pMan = new Ww1Manager( *pStrm, nFieldFlags ); + if( pMan ) + { + if( !pMan->GetError() ) + { + ::StartProgress( STR_STATSTR_W4WREAD, 0, 100, + rDoc.GetDocShell() ); + ::SetProgressState( 0, rDoc.GetDocShell() ); + // jetzt nur noch alles rueberschieben + *pRdr << *pMan; + if( !pMan->GetError() ) + // und nur hier, wenn kein fehler auftrat + // fehlerfreiheit melden + nRet = 0; // besser waere: WARN_SWG_FEATURES_LOST; + ::EndProgress( rDoc.GetDocShell() ); + } + else + { + if( pMan->GetFib().GetFIB().fComplexGet() ) + //!!! ACHTUNG: hier muss eigentlich ein Error + // wegen Fastsave kommen, das der PMW-Filter + // das nicht unterstuetzt. Stattdessen temporaer + // nur eine Warnung, bis die entsprechende + // Meldung und Behandlung weiter oben eingebaut ist. +// nRet = WARN_WW6_FASTSAVE_ERR; + // Zum Einchecken mit neuem String: + nRet = ERR_WW6_FASTSAVE_ERR; + } + } + delete pMan; + } + delete pRdr; + } + Ww1Sprm::DeinitTab(); + return nRet; +} + +///////////////////////////////////////////////////////////////// Shell +// +// Die Shell ist die Schnittstelle vom Filter zum Writer. Sie ist +// abgeleitet von der mit ww-filter gemeinsam benutzten Shell +// SwFltShell und enthaelt alle fuer ww1 noetigen Erweiterungen. Wie +// in einen Stream werden alle Informationen, die aus der Datei +// gelesen werden, in die shell ge'piped'. +// +Ww1Shell::Ww1Shell( SwDoc& rD, SwPaM& rPam, const String& rBaseURL, BOOL bNew, ULONG nFieldFlags) + : SwFltShell(&rD, rPam, rBaseURL, bNew, nFieldFlags) +{ +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww1/w1par.hxx b/sw/source/filter/ww1/w1par.hxx new file mode 100644 index 000000000000..01f5d66a7d97 --- /dev/null +++ b/sw/source/filter/ww1/w1par.hxx @@ -0,0 +1,45 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef _W1PAR_HXX +#define _W1PAR_HXX + +#include <fltshell.hxx> +#include <w1class.hxx> + +////////////////////////////////////////////////////////////// Ww1Shell +class Ww1Shell : public SwFltShell +{ +public: + Ww1Shell(SwDoc&, SwPaM&, const String& rBaseURL, BOOL bNew, ULONG nFieldFlags); +}; + + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww1/w1sprm.cxx b/sw/source/filter/ww1/w1sprm.cxx new file mode 100644 index 000000000000..920370622aee --- /dev/null +++ b/sw/source/filter/ww1/w1sprm.cxx @@ -0,0 +1,690 @@ +/* -*- 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + +#include <hintids.hxx> +#include <tools/solar.h> +#include <editeng/paperinf.hxx> +#include <editeng/lrspitem.hxx> +#include <editeng/adjitem.hxx> +#include <editeng/spltitem.hxx> +#include <editeng/keepitem.hxx> +#include <editeng/boxitem.hxx> +#include <editeng/shaditem.hxx> +#include <editeng/ulspitem.hxx> +#include <editeng/lspcitem.hxx> +#include <editeng/tstpitem.hxx> +#include <fmtclds.hxx> +#include <fmtfsize.hxx> +#include <pam.hxx> +#include <ndtxt.hxx> +#include <charatr.hxx> +#include <frmatr.hxx> +#include <doc.hxx> +#include <errhdl.hxx> +#include <fltini.hxx> +#include <docufld.hxx> +#include <pagedesc.hxx> +#include <flddat.hxx> +#include <reffld.hxx> +#include <expfld.hxx> +#include <w1par.hxx> +#include <mdiexp.hxx> +#include <swerror.h> +#include <statstr.hrc> + +using namespace ::com::sun::star; + +/////////////////////////////////////////////////////////////// Ww1Sprm +void Ww1Sprm::Stop( Ww1Shell& rOut, Ww1Manager& rMan) +{ + if(IsUsed()) + for(short i=Count()-1;i>=0;i--){ // rueckwaerts + BYTE nId; + USHORT nSize; + BYTE* pSprm; + Fill(i, nId, nSize, pSprm); + GetTab(nId).Stop(rOut, nId, pSprm, nSize, rMan); + } +} + +void Ww1Sprm::Start( + Ww1Shell& rOut, Ww1Manager& rMan, USHORT i) +{ + BYTE nId; + USHORT nSize; + BYTE* pSprm; + Fill(i, nId, nSize, pSprm); + GetTab(nId).Start(rOut, nId, pSprm, nSize, rMan); +} + +void Ww1Sprm::Start( + Ww1Shell& rOut, Ww1Manager& rMan) +{ + if(IsUsed()) + for(USHORT i=0;i<Count();i++) + Start(rOut, rMan, i); +} + +//////////////////////////////////////////////////////////// SingleSprm +void Ww1SingleSprm::Start( + Ww1Shell&, BYTE /*nId*/, BYTE*, USHORT, Ww1Manager&) +{ +} + +void Ww1SingleSprm::Stop( + Ww1Shell&, BYTE, BYTE*, USHORT, Ww1Manager&) +{ +// OSL_ENSURE(FALSE, "Unknown Sprm"); +} + +////////////////////////////////////////////////////////////////// STOP +// +// folgende defines werden genutzt zur implementierung der +// Stop()-Member der SingleSprm-klassen, da diese im normalfalle +// lediglich EndItem(s) in die shell stellen. +// +#define STOP1(Class, Code) \ + void Class::Stop( \ + Ww1Shell& rOut, BYTE, BYTE*, USHORT, Ww1Manager&) { \ + rOut.EndItem(Code); } +#define STOP2(Class, Code1, Code2) \ + void Class::Stop( \ + Ww1Shell& rOut, BYTE, BYTE*, USHORT, Ww1Manager&) { \ + rOut.EndItem(Code1).EndItem(Code2); } + +/////////////////////////////////////////////////////// SingleSprmXxxxx +// +// hier beginnt die auswertung der eigentlichen sprms. jeder sprmtyp +// hat eine eigene klasse, die die virtualen methoden start und stop +// implementiert. die klassen stehen in der sprm-tab, die statischer +// member von Ww1Sprm ist. taucht ein sprm im dokument auf, werden die +// virtualen methoden bei beginn und ende der formatierung gerufen. +// +void Ww1SingleSprmPDxaLeft::Start( + Ww1Shell& rOut, BYTE, BYTE* pSprm, USHORT, Ww1Manager&) +{ + SvxLRSpaceItem aLR((SvxLRSpaceItem&)rOut.GetAttr(RES_LR_SPACE)); + short nPara = SVBT16ToShort(pSprm); + if(nPara < 0) + nPara = 0; + if(aLR.GetTxtFirstLineOfst() < -nPara) + aLR.SetTxtFirstLineOfst(-nPara); // sonst weigert sich SetTxtLeft() + aLR.SetTxtLeft(nPara); + rOut << aLR; +} + +void Ww1SingleSprmPDxaRight::Start( + Ww1Shell& rOut, BYTE, BYTE* pSprm, USHORT, Ww1Manager&) +{ + SvxLRSpaceItem aLR((SvxLRSpaceItem&)rOut.GetAttr(RES_LR_SPACE)); + short nPara = SVBT16ToShort(pSprm); + if(nPara < 0) + nPara = 0; + aLR.SetRight(nPara); + rOut << aLR; +} + +void Ww1SingleSprmPDxaLeft1::Start( + Ww1Shell& rOut, BYTE, BYTE* pSprm, USHORT, Ww1Manager&) +{ + SvxLRSpaceItem aLR((SvxLRSpaceItem&)rOut.GetAttr(RES_LR_SPACE)); + short nPara = SVBT16ToShort(pSprm); + if(-nPara >(short)aLR.GetTxtLeft()) + nPara = -(short)aLR.GetTxtLeft(); + aLR.SetTxtFirstLineOfst(nPara); + rOut << aLR; +} + +STOP1(Ww1SingleSprmPDxa, RES_LR_SPACE) + +void Ww1SingleSprmPJc::Start( + Ww1Shell& rOut, BYTE, BYTE* pSprm, USHORT, Ww1Manager&) +{ + static SvxAdjust __READONLY_DATA aAdj[] = { + SVX_ADJUST_LEFT, + SVX_ADJUST_CENTER, + SVX_ADJUST_RIGHT, + SVX_ADJUST_BLOCK }; + BYTE nPara = SVBT8ToByte(pSprm); + nPara %=(sizeof(aAdj)/sizeof(*aAdj)); + rOut << SvxAdjustItem(aAdj[nPara], RES_PARATR_ADJUST); +} + +STOP1(Ww1SingleSprmPJc, RES_PARATR_ADJUST) + +void Ww1SingleSprmPFKeep::Start( + Ww1Shell& rOut, BYTE, BYTE* pSprm, USHORT, Ww1Manager&) +{ + rOut << SvxFmtSplitItem((SVBT8ToByte(pSprm) & 1) == 0, RES_PARATR_SPLIT); +} + +STOP1(Ww1SingleSprmPFKeep, RES_PARATR_SPLIT) + +void Ww1SingleSprmPFKeepFollow::Start( + Ww1Shell& rOut, BYTE, BYTE* pSprm, USHORT, Ww1Manager&) +{ + rOut << SvxFmtKeepItem((SVBT8ToByte(pSprm) & 1) != 0, RES_KEEP); +} + +STOP1(Ww1SingleSprmPFKeepFollow, RES_KEEP) + +void Ww1SingleSprmPPageBreakBefore::Start( + Ww1Shell& rOut, BYTE, BYTE* pSprm, USHORT, Ww1Manager&) +{ + rOut << SvxFmtBreakItem(SVBT8ToByte(pSprm) & 1? + SVX_BREAK_PAGE_BEFORE:SVX_BREAK_NONE, RES_BREAK ); +} + +STOP1(Ww1SingleSprmPPageBreakBefore, RES_BREAK) + +SvxBorderLine* Ww1SingleSprmPBrc::SetBorder(SvxBorderLine* pLine, W1_BRC10* pBrc) +{ + USHORT nCode; + SvxBorderStyle eStyle = SOLID; + if(pBrc->dxpLine2WidthGet() == 0) + { + switch(pBrc->dxpLine1WidthGet()) + { + default: OSL_ENSURE(FALSE, "unknown linewidth"); + case 0: return 0; // keine Linie + case 1: nCode = DEF_LINE_WIDTH_0; break; + case 2: nCode = DEF_LINE_WIDTH_1; break; + case 3: nCode = DEF_LINE_WIDTH_2; break; + case 4: nCode = DEF_LINE_WIDTH_3; break; + case 5: nCode = DEF_LINE_WIDTH_4; break; + case 6: + nCode = DEF_LINE_WIDTH_5; + eStyle = DOTTED; + break; + case 7: + nCode = DEF_LINE_WIDTH_5; + eStyle = DASHED; + break; + } + pLine->SetOutWidth(nCode); + pLine->SetInWidth(0); + pLine->SetStyle( eStyle ); + } + else + { + switch(pBrc->dxpLine1WidthGet()) + { + default: OSL_ENSURE(FALSE, "unknown linewidth"); + case 1: nCode = DEF_DOUBLE_LINE0_IN; break; + } + pLine->SetOutWidth(nCode); + switch(pBrc->dxpLine2WidthGet()) + { + default: OSL_ENSURE(FALSE, "unknown linewidth"); + case 1: nCode = DEF_DOUBLE_LINE0_OUT; break; + } + pLine->SetInWidth(nCode); + } + switch(pBrc->dxpLine1WidthGet()) + { + default: OSL_ENSURE(FALSE, "unknown space"); + case 0: nCode = DEF_DOUBLE_LINE0_DIST; break; + case 1: nCode = DEF_DOUBLE_LINE1_DIST; break; + case 2: nCode = DEF_DOUBLE_LINE2_DIST; break; + case 3: nCode = DEF_DOUBLE_LINE3_DIST; break; + } + pLine->SetDistance(nCode); + return pLine; +} + +void Ww1SingleSprmPBrc::Start( + Ww1Shell& rOut, BYTE, + W1_BRC10* pBrc, + USHORT +#if OSL_DEBUG_LEVEL > 1 + nSize +#endif + , + Ww1Manager& /*rMan*/, + SvxBoxItem& aBox) +{ +#if OSL_DEBUG_LEVEL > 1 + OSL_ENSURE(sizeof(W1_BRC10) == nSize, "sizemissmatch"); +#endif + if(pBrc->dxpSpaceGet()) + aBox.SetDistance(10 + 20 * pBrc->dxpSpaceGet()); + //??? Warum 10+... ???? + + if( rOut.IsInFly() ) + rOut.SetFlyFrmAttr( aBox ); + else + rOut << aBox; + + if(pBrc->fShadowGet()) + { + Color aBlack(COL_BLACK); // schwarzer... + SvxShadowItem aS(RES_SHADOW,(const Color*)&aBlack, 32, + SVX_SHADOW_BOTTOMRIGHT); // 1.6 tw breit + if( rOut.IsInFly() ) + rOut.SetFlyFrmAttr( aS ); + else + rOut << aS; + } +} + +STOP2(Ww1SingleSprmPBrc, RES_BOX, RES_SHADOW) + +static USHORT __READONLY_DATA nBrcTrans[BRC_ANZ] = + { BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT }; + +void Ww1SingleSprmPBrc10::Start( + Ww1Shell& rOut, BYTE nId, BYTE* pSprm, USHORT nSize, Ww1Manager& rMan) +{ + + W1_BRC10* pBrc =(W1_BRC10*)pSprm; + const SfxPoolItem &rItem = ( ( rOut.IsInFly() ) ? + rOut.GetFlyFrmAttr(RES_BOX) :rOut.GetAttr(RES_BOX)); + const SvxBoxItem &rBoxItem = (const SvxBoxItem&)rItem; + SvxBoxItem aBox( rBoxItem ); + SvxBorderLine aLine; + aBox.SetLine(SetBorder(&aLine, pBrc), nBrcTrans[nLine] ); + Ww1SingleSprmPBrc::Start(rOut, nId, pBrc, nSize, rMan, aBox); +} + +STOP1(Ww1SingleSprmParaSpace, RES_UL_SPACE) + +void Ww1SingleSprmPDyaBefore::Start( + Ww1Shell& rOut, BYTE /*nId*/, BYTE* pSprm, USHORT /*nSize*/, Ww1Manager& /*rMan*/) +{ + short nPara = SVBT16ToShort(pSprm); + if(nPara < 0) + nPara = -nPara; + SvxULSpaceItem aUL((SvxULSpaceItem&)rOut.GetAttr(RES_UL_SPACE)); + aUL.SetUpper(nPara); + rOut << aUL; +} + +void Ww1SingleSprmPDyaAfter::Start( + Ww1Shell& rOut, BYTE /*nId*/, BYTE* pSprm, USHORT /*nSize*/, Ww1Manager& /*rMan*/) +{ + short nPara = SVBT16ToShort(pSprm); + if(nPara < 0) + nPara = -nPara; + SvxULSpaceItem aUL((SvxULSpaceItem&)rOut.GetAttr(RES_UL_SPACE)); + aUL.SetLower(nPara); + rOut << aUL; +} + +STOP1(Ww1SingleSprmPDyaLine, RES_PARATR_LINESPACING) + +void Ww1SingleSprmPDyaLine::Start( + Ww1Shell& rOut, BYTE /*nId*/, BYTE* pSprm, USHORT /*nSize*/, Ww1Manager& /*rMan*/) +{ + short nSpace = SVBT16ToShort(pSprm); + if(nSpace < 0) + nSpace = -nSpace; + SvxLineSpacingItem aLSpc( LINE_SPACE_DEFAULT_HEIGHT, RES_PARATR_LINESPACING ); + if(TRUE) + {// MultilineSpace(proportional) + long n = nSpace * 100 / 240; // W1: 240 = 100%, SW: 100 = 100% + if(n>200) + n = 200; // SW_UI-Maximum + aLSpc.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO; + aLSpc.SetPropLineSpace((BYTE)n); + } + else + {// Fixed / Minimum + aLSpc.SetLineHeight((USHORT)nSpace); + aLSpc.GetInterLineSpaceRule() = SVX_INTER_LINE_SPACE_OFF; + } + rOut << aLSpc; +} + +void Ww1SingleSprmPChgTabsPapx::Start( + Ww1Shell& rOut, BYTE /*nId*/, BYTE* pSprm, USHORT /*nSize*/, Ww1Manager& /*rMan*/) +{ + + short nLeftPMgn = 0; // Koordinaten etwa gleich ?? + + short i; + BYTE nDel = pSprm[1]; + BYTE* pDel = pSprm + 2; // Del - Array + BYTE nIns = pSprm[nDel*2+2]; + BYTE* pIns = pSprm + 2*nDel + 3; // Ins - Array + W1_TBD* pTyp = (W1_TBD*)(pSprm + 2*nDel + 2*nIns + 3);// Typ - Array + + SvxTabStopItem aAttr( (SvxTabStopItem&)rOut.GetNodeOrStyAttr( RES_PARATR_TABSTOP )); + + SvxTabStop aTabStop; + + for( i=0; i<nDel; i++ ){ + USHORT nPos = aAttr.GetPos( SVBT16ToShort( pDel + i*2 ) - nLeftPMgn ); + if( nPos != SVX_TAB_NOTFOUND ) + aAttr.Remove( nPos, 1 ); + } + + for( i=0; i<nIns; i++ ){ + short nPos = SVBT16ToShort( pIns + i*2 ) - nLeftPMgn; + if( nPos < 0 ) + continue; + aTabStop.GetTabPos() = nPos; + switch( pTyp[i].jcGet() ){ + case 0: aTabStop.GetAdjustment() = SVX_TAB_ADJUST_LEFT; break; + case 1: aTabStop.GetAdjustment() = SVX_TAB_ADJUST_CENTER; break; + case 2: aTabStop.GetAdjustment() = SVX_TAB_ADJUST_RIGHT; break; + case 3: aTabStop.GetAdjustment() = SVX_TAB_ADJUST_DECIMAL; break; + case 4: continue; // ignoriere Bar + } + + switch( pTyp[i].tlcGet() ){ + case 0: aTabStop.GetFill() = ' '; break; + case 1: aTabStop.GetFill() = '.'; break; + case 2: aTabStop.GetFill() = '-'; break; + case 3: + case 4: aTabStop.GetFill() = '_'; break; + } + + USHORT nPos2 = aAttr.GetPos( nPos ); + if( nPos2 != SVX_TAB_NOTFOUND ) + aAttr.Remove( nPos2, 1 ); // sonst weigert sich das Insert() + + aAttr.Insert( aTabStop ); + } + rOut << aAttr; +} + +STOP1(Ww1SingleSprmPChgTabsPapx, RES_PARATR_TABSTOP) + +void Ww1SingleSprmSGprfIhdt::Start( + Ww1Shell& /*rOut*/, BYTE /*nId*/, BYTE* pSprm, USHORT /*nSize*/, Ww1Manager& rMan) +{ + rMan.GetSep().SetGrpfIhdt(SVBT8ToByte(pSprm)); +} + +void Ww1SingleSprmSColumns::Start( + Ww1Shell& rOut, BYTE /*nId*/, BYTE* pSprm, USHORT /*nSize*/, Ww1Manager& /*rMan*/) +{ + short nColSpace = 708; // default 1,25 cm + short nNettoWidth = -1; //~ mdt: dxaLeft/Right missing... + short nCols = SVBT16ToShort(pSprm); + nCols++; + if (nCols < 2) + return; + SwFmtCol aCol; + aCol.Init(nCols, nColSpace, nNettoWidth); + rOut.GetPageDesc().GetMaster().SetFmtAttr(aCol); +} + +void Ww1SingleSprmPTtp::Start( + Ww1Shell& /*rOut*/, BYTE, BYTE*, USHORT, Ww1Manager& rMan) +{ + rMan.SetInTtp( TRUE ); // Besonderheit: wird bei InTable::Stop und + // nicht bei InTtp::Stop zurueckgesetzt, + // da Auswertung in InTable +} + +void Ww1SingleSprmPTtp::Stop( + Ww1Shell& rOut, BYTE, BYTE*, USHORT, Ww1Manager& rMan) +{ + if (rOut.IsInTable() && rMan.HasInTable()) + rOut.NextTableRow(); +} + +void Ww1SingleSprmPFInTable::Start( + Ww1Shell& /*rOut*/, BYTE, BYTE*, USHORT, + Ww1Manager& /*rMan*/) +{ +} + +void Ww1SingleSprmPFInTable::Stop( + Ww1Shell& +#if OSL_DEBUG_LEVEL > 1 + rOut +#endif + , + BYTE, BYTE*, USHORT, + Ww1Manager& rMan) +{ +#if OSL_DEBUG_LEVEL > 1 + OSL_ENSURE(rOut.IsInTable(), ""); +#endif + rMan.SetInTtp( FALSE ); +} + +void Ww1SingleSprmTDxaGapHalf::Start( + Ww1Shell& rOut, BYTE /*nId*/, BYTE* pSprm, USHORT /*nSize*/, Ww1Manager& /*rMan*/) +{ + short nSpace = SVBT16ToShort(pSprm); + rOut.SetCellSpace(nSpace); +} + +void Ww1SingleSprmTDefTable10::Start( + Ww1Shell& rOut, BYTE /*nId*/, BYTE* pSprm, USHORT nSize, Ww1Manager& /*rMan*/) +{ + USHORT i; + BYTE *p = pSprm + 2; // LaengenWord ueberlesen + BYTE nCount = *p; + p++; + nSize -= 3; +// Es fehlt noch: +// - GapHalf +// - eventuelle Ausduennung der Zellenumrandungen + + if( nCount < 1 || nCount > 32 || nSize < ( nCount + 1 ) * 2 ) + return; + +// Erstmal die Zellenpositionen einlesen + short nPos = SVBT16ToShort( p ); // signed, kann auch neg. sein !!! + + { + short nWholeWidth = SVBT16ToShort( p + 2 * nCount ) - nPos; + rOut.SetTableWidth( (USHORT)nWholeWidth ); // Tabellenbreite setzen + +// Pos der Tabelle setzen + long nMidTab = nPos + nWholeWidth / 2; // TabellenMitte + const SwFrmFmt &rFmt = rOut.GetPageDesc().GetMaster(); + const SvxLRSpaceItem& rLR = rFmt.GetLRSpace(); + long nRight = rFmt.GetFrmSize().GetWidth() + - rLR.GetLeft() - rLR.GetRight(); + + sal_Int16 eOri = text::HoriOrientation::LEFT; + if( nPos > MINLAY ){ // per Zuppeln positioniert + if ( nMidTab <= nRight / 3 ) // 1/3 der Seite + eOri = text::HoriOrientation::LEFT; + else if ( nMidTab <= 2 * nRight / 3 ) // 2/3 der Seite + eOri = text::HoriOrientation::CENTER; + else + eOri = text::HoriOrientation::RIGHT; + } + rOut.SetTableOrient( eOri ); + } + + BYTE* pEndPos = p+2; + BYTE* pTc0 = ( nSize >= nCount * 10 ) ? pEndPos + 2 * nCount : 0; + USHORT nCellsDeleted = 0; // fuer gemergte Zellen + + for( i = 0; i < nCount; i++ ){ +// Info sammeln + W1_TC* pTc = (W1_TC*)pTc0; + BOOL bMerged = (pTc) ? pTc->fMergedGet() : FALSE; + +// Zellenbreiten setzen + USHORT nPos1 = SVBT16ToShort( pEndPos ); + if( !bMerged ) + rOut.SetCellWidth( nPos1 - nPos, i - nCellsDeleted ); + // Zellenbreite setzen + // Wechselwirkung mit GapHalf fehlt noch + // ( GapHalf wird noch ignoriert ) + pEndPos+=2; + nPos = nPos1; + + if( pTc0 ){ // gibts TCs ueberhaupt ? + W1_TC* pTc2 = (W1_TC*)pTc0; + BOOL bMerged2 = pTc2->fMergedGet(); + if( !bMerged2 ){ +// und nun die Umrandungen + SvxBoxItem aBox( (SvxBoxItem&)rOut.GetCellAttr( RES_BOX )); + SvxBorderLine aLine; + W1_BRC10* pBrc = pTc2->rgbrcGet(); + for( USHORT j=0; j<4; j++ ){ + aBox.SetLine(Ww1SingleSprmPBrc::SetBorder(&aLine, pBrc), + nBrcTrans[j]); + pBrc++; + } + rOut.SetCellBorder( aBox, i - nCellsDeleted ); + }else{ +// gemergte Zellen entfernen + rOut.DeleteCell( i - nCellsDeleted ); + nCellsDeleted++; + } + pTc0+=sizeof(W1_TC); // 10 + } + } +} + + +void Ww1SingleSprmTDyaRowHeight::Start( + Ww1Shell& rOut, BYTE /*nId*/, BYTE* pSprm, USHORT /*nSize*/, Ww1Manager& /*rMan*/) +{ + short nSpace = SVBT16ToShort(pSprm); + rOut.SetCellHeight(nSpace); +} + +// Fastsave-Attribute brauche ich als Dymmys nicht + +void Ww1SingleSprmPpc::Start( + Ww1Shell& rOut, BYTE /*nId*/, BYTE* pSprm, USHORT /*nSize*/, Ww1Manager& rMan) +{ + BYTE nPpc = SVBT8ToByte(pSprm); + + if (rOut.IsInTable()) // Flys in Tabellen kann PMW + return; // nicht + + RndStdIds eAnchor; // Bindung + sal_Int16 eHRel; // Seite oder Seitenrand + sal_Int16 eVRel; // Seite oder Seitenrand + + switch ( ( nPpc & 0x30 ) >> 4 ){ // Y - Bindung bestimmt Sw-Bindung + case 0: eAnchor = FLY_AT_PARA; // Vert Margin + eVRel = text::RelOrientation::PRINT_AREA; + + break; + + default:eAnchor = FLY_AT_PAGE; // Vert Page oder unknown + eVRel = text::RelOrientation::FRAME; + break; // 2=Vert. Paragraph, 3=Use Default + } + + switch ( ( nPpc & 0xc0 ) >> 6 ){ // X - Bindung -> Koordinatentransformation + case 0: // Hor. Spalte + case 1: // Hor. Absatz + eHRel = text::RelOrientation::PRINT_AREA; + + break; + + default: + eHRel = text::RelOrientation::FRAME; + break; + } + + if( !rOut.IsInFly() && rMan.IsInStyle() ){ + rOut.BeginFly( eAnchor ); // Starte StyleFly + }else{ + rOut.SetFlyAnchor( eAnchor ); // Setze Anker + } +} + +void Ww1SingleSprmPDxaAbs::Start( + Ww1Shell& rOut, BYTE /*nId*/, BYTE* pSprm, USHORT /*nSize*/, Ww1Manager& rMan) +{ + short nXPos = SVBT16ToShort(pSprm); + + if( rMan.IsInStyle() && !rOut.IsInFly() ){ + rOut.BeginFly(); // Fly ohne PPc-Attribut + } + + sal_Int16 eHRel = text::RelOrientation::FRAME; + sal_Int16 eHAlign = text::HoriOrientation::NONE; + + switch( nXPos ){ // besondere X-Positionen ? + case 0: + case -12: eHAlign = text::HoriOrientation::NONE; nXPos = 0; break; // Mogel: innen -> links + // eigentich text::HoriOrientation::LEFT, aber dann verrueckt + // ein Abstand nach aussen den Fly + case -4: eHAlign = text::HoriOrientation::CENTER; nXPos = 0; break; // zentriert + case -8: // rechts + case -16: eHAlign = text::HoriOrientation::RIGHT; nXPos = 0; break; // Mogel: aussen -> rechts + + } + rOut.SetFlyXPos( nXPos, eHRel, eHAlign ); +} + +void Ww1SingleSprmPDyaAbs::Start( + Ww1Shell& rOut, BYTE /*nId*/, BYTE* pSprm, USHORT /*nSize*/, Ww1Manager& /*rMan*/) +{ + short nYPos = SVBT16ToShort(pSprm); + sal_Int16 eVRel = text::RelOrientation::FRAME; + sal_Int16 eVAlign = text::VertOrientation::NONE; + + switch( nYPos ){ // besondere Y-Positionen ? + case -4: eVAlign = text::VertOrientation::TOP; nYPos = 0; break; // oben + case -8: eVAlign = text::VertOrientation::CENTER; nYPos = 0; break; // zentriert + case -12: eVAlign = text::VertOrientation::BOTTOM; nYPos = 0; break; // unten + + } + rOut.SetFlyYPos( nYPos, eVRel, eVAlign ); +} + +void Ww1SingleSprmPDxaWidth::Start( + Ww1Shell& rOut, BYTE /*nId*/, BYTE* pSprm, USHORT /*nSize*/, Ww1Manager& /*rMan*/) +{ + short nDxaWidth = SVBT16ToShort(pSprm); + rOut.SetFlyFrmAttr( SwFmtFrmSize( ATT_VAR_SIZE, nDxaWidth, MINFLY ) ); +} + +void Ww1SingleSprmPFromText::Start( + Ww1Shell& rOut, BYTE /*nId*/, BYTE* pSprm, USHORT /*nSize*/, Ww1Manager& /*rMan*/) +{ + if( rOut.IsInFly() ){ // Kommt auch ausserhalb eines Flys vor, hat + // dann aber offensichtlich nichts zu bedeuten. + // Einen impliziten Fly-Anfang bedeutet es + // definitiv nicht + short nFromText = SVBT16ToShort(pSprm); + + SvxLRSpaceItem aLR( RES_LR_SPACE ); + aLR.SetTxtLeft( nFromText ); + aLR.SetRight( nFromText ); + rOut.SetFlyFrmAttr( aLR ); + + rOut.SetFlyFrmAttr( SvxULSpaceItem( nFromText, nFromText, RES_UL_SPACE ) ); + } +} + +#undef STOP1 +#undef STOP2 + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww1/w1struct.hxx b/sw/source/filter/ww1/w1struct.hxx new file mode 100644 index 000000000000..0cc2d7cf8c62 --- /dev/null +++ b/sw/source/filter/ww1/w1struct.hxx @@ -0,0 +1,853 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifndef W1STRUCT_HXX +#define W1STRUCT_HXX + +// star view +#include <string.h> +#include <tools/solar.h> + +class Ww1Shell; +class Ww1Manager; + +struct W1_FIB ///////////////////////////////////////////////////////// +{ + SVBT16 wIdent;// 0x0 int magic number + USHORT wIdentGet() { + return SVBT16ToShort(wIdent); } + SVBT16 nFib;// 0x2 FIB version written + USHORT nFibGet() { + return SVBT16ToShort(nFib); } + SVBT16 nProduct;// 0x4 product version written by + USHORT nProductGet() { + return SVBT16ToShort(nProduct); } + SVBT16 nlocale;// 0x6 language stamp---localized version; + USHORT nlocaleGet() { + return SVBT16ToShort(nlocale); } + SVBT16 pnNext;// 0x8 + USHORT pnNextGet() { + return SVBT16ToShort(pnNext); } + SVBT16 fFlags; + USHORT fFlagsGet() { + return SVBT16ToShort(fFlags); } + // SVBT16 fDot :1;// 0xa 0001 + BOOL fDotGet() { + return 0 != ((fFlagsGet() >> 0) & 1); } + // SVBT16 fGlsy :1;// 0002 + BOOL fGlsyGet() { + return 0 != ((fFlagsGet() >> 1) & 1); } + // SVBT16 fComplex :1;// 0004 when 1, file is in complex, fast-saved format. + BOOL fComplexGet() { + return 0 != ((fFlagsGet() >> 2) & 1); } + // SVBT16 fHasPic :1;// 0008 file contains 1 or more pictures + BOOL fHasPicGet() { + return 0 != ((fFlagsGet() >> 3) & 1); } + // SVBT16 cQuickSaves :4;// 00F0 count of times file was quicksaved + USHORT cQuickSavesGet() { + return (USHORT)((fFlagsGet() >> 4) & 0xf); } + // SVBT16 u1 :8;// FF00 unused + USHORT u1Get() { + return (USHORT)((fFlagsGet() >> 8) & 0xff); } + SVBT16 nFibBack;// 0xc + USHORT nFibBackGet() { + return SVBT16ToShort(nFibBack); } + SVBT16 u2[5];// 0xe reserved + SVBT32 fcMin;// 0x18 file offset of first character of text + ULONG fcMinGet() { + return SVBT32ToUInt32(fcMin); } + SVBT32 fcMac;// 0x1c file offset of last character of text + 1 + ULONG fcMacGet() { + return SVBT32ToUInt32(fcMac); } + SVBT32 cbMac;// 0x20 file offset of last byte written to file + 1. + ULONG cbMacGet() { + return SVBT32ToUInt32(cbMac); } + SVBT32 u4[4];// 0x24 reserved + SVBT32 ccpText;// 0x34 length of main document text stream + ULONG ccpTextGet() { + return SVBT32ToUInt32(ccpText); } + SVBT32 ccpFtn;// 0x38 length of footnote subdocument text stream + ULONG ccpFtnGet() { + return SVBT32ToUInt32(ccpFtn); } + SVBT32 ccpHdd;// 0x3c length of header subdocument text stream + ULONG ccpHddGet() { + return SVBT32ToUInt32(ccpHdd); } + SVBT32 ccpMcr;// 0x40 length of macro subdocument text stream + ULONG ccpMcrGet() { + return SVBT32ToUInt32(ccpMcr); } + SVBT32 ccpAtn;// 0x44 length of annotation subdocument text stream + ULONG ccpAtnGet() { + return SVBT32ToUInt32(ccpAtn); } + SVBT32 cp5[4];// 0x48 + SVBT32 fcStshfOrig;// 0x58 file offset of original allocation for STSH in file + ULONG fcStshfOrigGet() { + return SVBT32ToUInt32(fcStshfOrig); } + SVBT16 cbStshfOrig;// 0x5c count of bytes of original STSH allocation + USHORT cbStshfOrigGet() { + return SVBT16ToShort(cbStshfOrig); } + SVBT32 fcStshf;// 0x5e file offset of STSH in file. + ULONG fcStshfGet() { + return SVBT32ToUInt32(fcStshf); } + SVBT16 cbStshf;// 0x62 count of bytes of current STSH allocation + USHORT cbStshfGet() { + return SVBT16ToShort(cbStshf); } + SVBT32 fcPlcffndRef;// 0x64 file offset of footnote reference PLC. + ULONG fcPlcffndRefGet() { + return SVBT32ToUInt32(fcPlcffndRef); } + SVBT16 cbPlcffndRef;// 0x68 count of bytes of footnote reference PLC + USHORT cbPlcffndRefGet() { + return SVBT16ToShort(cbPlcffndRef); } + // == 0 if no footnotes defined in document. + + SVBT32 fcPlcffndTxt;// 0x6a file offset of footnote text PLC. + ULONG fcPlcffndTxtGet() { + return SVBT32ToUInt32(fcPlcffndTxt); } + SVBT16 cbPlcffndTxt;// 0x6e count of bytes of footnote text PLC. + USHORT cbPlcffndTxtGet() { + return SVBT16ToShort(cbPlcffndTxt); } + // == 0 if no footnotes defined in document + + SVBT32 fcPlcfandRef;// 0x70 file offset of annotation reference PLC. + ULONG fcPlcfandRefGet() { + return SVBT32ToUInt32(fcPlcfandRef); } + SVBT16 cbPlcfandRef;// 0x74 count of bytes of annotation reference PLC. + USHORT cbPlcfandRefGet() { + return SVBT16ToShort(cbPlcfandRef); } + + SVBT32 fcPlcfandTxt;// 0x76 file offset of annotation text PLC. + ULONG fcPlcfandTxtGet() { + return SVBT32ToUInt32(fcPlcfandTxt); } + SVBT16 cbPlcfandTxt;// 0x7a count of bytes of the annotation text PLC + USHORT cbPlcfandTxtGet() { + return SVBT16ToShort(cbPlcfandTxt); } + + SVBT32 fcPlcfsed;// 8x7c file offset of section descriptor PLC. + ULONG fcPlcfsedGet() { + return SVBT32ToUInt32(fcPlcfsed); } + SVBT16 cbPlcfsed;// 0x80 count of bytes of section descriptor PLC. + USHORT cbPlcfsedGet() { + return SVBT16ToShort(cbPlcfsed); } + + SVBT32 fcPlcfpgd;// 0x82 file offset of paragraph descriptor PLC + ULONG fcPlcfpgdGet() { + return SVBT32ToUInt32(fcPlcfpgd); } + SVBT16 cbPlcfpgd;// 0x86 count of bytes of paragraph descriptor PLC. + USHORT cbPlcfpgdGet() { + return SVBT16ToShort(cbPlcfpgd); } + // ==0 if file was never repaginated + // Should not be written by third party creators + + SVBT32 fcPlcfphe;// 0x88 file offset of PLC of paragraph heights. + ULONG fcPlcfpheGet() { + return SVBT32ToUInt32(fcPlcfphe); } + SVBT16 cbPlcfphe;// 0x8c count of bytes of paragraph height PLC. + USHORT cbPlcfpheGet() { + return SVBT16ToShort(cbPlcfphe); } + // ==0 when file is non-complex. + + SVBT32 fcSttbfglsy;// 0x8e file offset of glossary string table. + ULONG fcSttbfglsyGet() { + return SVBT32ToUInt32(fcSttbfglsy); } + SVBT16 cbSttbfglsy;// 0x92 count of bytes of glossary string table. + USHORT cbSttbfglsyGet() { + return SVBT16ToShort(cbSttbfglsy); } + // == 0 for non-glossary documents. + // !=0 for glossary documents. + + SVBT32 fcPlcfglsy;// 0x94 file offset of glossary PLC. + ULONG fcPlcfglsyGet() { + return SVBT32ToUInt32(fcPlcfglsy); } + SVBT16 cbPlcfglsy;// 0x98 count of bytes of glossary PLC. + USHORT cbPlcfglsyGet() { + return SVBT16ToShort(cbPlcfglsy); } + // == 0 for non-glossary documents. + // !=0 for glossary documents. + + SVBT32 fcPlcfhdd;// 0x9a byte offset of header PLC. + ULONG fcPlcfhddGet() { + return SVBT32ToUInt32(fcPlcfhdd); } + SVBT16 cbPlcfhdd;// 0x9e count of bytes of header PLC. + USHORT cbPlcfhddGet() { + return SVBT16ToShort(cbPlcfhdd); } + // == 0 if document contains no headers + + SVBT32 fcPlcfbteChpx;// 0xa0 file offset of character property bin table.PLC. + ULONG fcPlcfbteChpxGet() { + return SVBT32ToUInt32(fcPlcfbteChpx); } + SVBT16 cbPlcfbteChpx;// 0xa4 count of bytes of character property bin table PLC. + USHORT cbPlcfbteChpxGet() { + return SVBT16ToShort(cbPlcfbteChpx); } + + SVBT32 fcPlcfbtePapx;// 0xa6 file offset of paragraph property bin table.PLC. + ULONG fcPlcfbtePapxGet() { + return SVBT32ToUInt32(fcPlcfbtePapx); } + SVBT16 cbPlcfbtePapx;// 0xaa count of bytes of paragraph property bin table PLC. + USHORT cbPlcfbtePapxGet() { + return SVBT16ToShort(cbPlcfbtePapx); } + + SVBT32 fcPlcfsea;// 0xac file offset of PLC reserved for private use. The SEA is 6 bytes long. + ULONG fcPlcfseaGet() { + return SVBT32ToUInt32(fcPlcfsea); } + SVBT16 cbPlcfsea;// 0xb0 count of bytes of private use PLC. + USHORT cbPlcfseaGet() { + return SVBT16ToShort(cbPlcfsea); } + + SVBT32 fcSttbfffn;// 0xb2 file offset of font information STTBF. See the FFN file structure definition. + ULONG fcSttbfffnGet() { + return SVBT32ToUInt32(fcSttbfffn); } + SVBT16 cbSttbfffn;// 0xb6 count of bytes in sttbfffn. + USHORT cbSttbfffnGet() { + return SVBT16ToShort(cbSttbfffn); } + + SVBT32 fcPlcffldMom;// 0xb8 offset in doc stream to the PLC of field positions in the main document. + ULONG fcPlcffldMomGet() { + return SVBT32ToUInt32(fcPlcffldMom); } + SVBT16 cbPlcffldMom;// 0xbc + USHORT cbPlcffldMomGet() { + return SVBT16ToShort(cbPlcffldMom); } + + SVBT32 fcPlcffldHdr;// 0xbe offset in doc stream to the PLC of field positions in the header subdocument. + ULONG fcPlcffldHdrGet() { + return SVBT32ToUInt32(fcPlcffldHdr); } + SVBT16 cbPlcffldHdr;// 0xc2 + USHORT cbPlcffldHdrGet() { + return SVBT16ToShort(cbPlcffldHdr); } + + SVBT32 fcPlcffldFtn;// 0xc4 offset in doc stream to the PLC of field positions in the footnote subdocument. + ULONG fcPlcffldFtnGet() { + return SVBT32ToUInt32(fcPlcffldFtn); } + SVBT16 cbPlcffldFtn;// 0xc8 + USHORT cbPlcffldFtnGet() { + return SVBT16ToShort(cbPlcffldFtn); } + + SVBT32 fcPlcffldAtn;// 0xca offset in doc stream to the PLC of field positions in the annotation subdocument. + ULONG fcPlcffldAtnGet() { + return SVBT32ToUInt32(fcPlcffldAtn); } + SVBT16 cbPlcffldAtn;// 0xce + USHORT cbPlcffldAtnGet() { + return SVBT16ToShort(cbPlcffldAtn); } + + SVBT32 fcPlcffldMcr;// 0xd0 offset in doc stream to the PLC of field positions in the macro subdocument. + ULONG fcPlcffldMcrGet() { + return SVBT32ToUInt32(fcPlcffldMcr); } + SVBT16 cbPlcffldMcr;// 0xd4 + USHORT cbPlcffldMcrGet() { + return SVBT16ToShort(cbPlcffldMcr); } + + SVBT32 fcSttbfbkmk;// 0xd6 offset in document stream of the STTBF that records bookmark names in the main document + ULONG fcSttbfbkmkGet() { + return SVBT32ToUInt32(fcSttbfbkmk); } + SVBT16 cbSttbfbkmk;// 0xda + USHORT cbSttbfbkmkGet() { + return SVBT16ToShort(cbSttbfbkmk); } + + SVBT32 fcPlcfbkf;// 0xdc offset in document stream of the PLCF that records the beginning CP offsets of bookmarks in the main document. See BKF + ULONG fcPlcfbkfGet() { + return SVBT32ToUInt32(fcPlcfbkf); } + SVBT16 cbPlcfbkf;// 0xe0 + USHORT cbPlcfbkfGet() { + return SVBT16ToShort(cbPlcfbkf); } + + SVBT32 fcPlcfbkl;// 0xe2 offset in document stream of the PLCF that records the ending CP offsets of bookmarks recorded in the main document. See the BKL structure definition. + ULONG fcPlcfbklGet() { + return SVBT32ToUInt32(fcPlcfbkl); } + SVBT16 cbPlcfbkl;// 0xe6 SVBT16 + USHORT cbPlcfbklGet() { + return SVBT16ToShort(cbPlcfbkl); } + + SVBT32 fcCmds;// 0xe8 FC + ULONG fcCmdsGet() { + return SVBT32ToUInt32(fcCmds); } + SVBT16 cbCmds;// 0xec + USHORT cbCmdsGet() { + return SVBT16ToShort(cbCmds); } + + SVBT32 fcPlcmcr;// 0xee FC + ULONG fcPlcmcrGet() { + return SVBT32ToUInt32(fcPlcmcr); } + SVBT16 cbPlcmcr;// 0xf2 + USHORT cbPlcmcrGet() { + return SVBT16ToShort(cbPlcmcr); } + + SVBT32 fcSttbfmcr;// 0xf4 FC + ULONG fcSttbfmcrGet() { + return SVBT32ToUInt32(fcSttbfmcr); } + SVBT16 cbSttbfmcr;// 0xf8 + USHORT cbSttbfmcrGet() { + return SVBT16ToShort(cbSttbfmcr); } + + SVBT32 fcPrEnv;// 0xfa + ULONG fcPrEnvGet() { + return SVBT32ToUInt32(fcPrEnv); } + SVBT16 cbPrEnv;// 0xfe + USHORT cbPrEnvGet() { + return SVBT16ToShort(cbPrEnv); } + + SVBT32 fcWss;// 0x100 file offset of Window Save State data structure. See WSS. + ULONG fcWssGet() { + return SVBT32ToUInt32(fcWss); } + SVBT16 cbWss;// 0x100 count of bytes of WSS. ==0 if unable to store the window state. + USHORT cbWssGet() { + return SVBT16ToShort(cbWss); } + + SVBT32 fcDop;// 0x106 file offset of document property data structure. + ULONG fcDopGet() { + return SVBT32ToUInt32(fcDop); } + SVBT16 cbDop;// 0x10a count of bytes of document properties. + USHORT cbDopGet() { + return SVBT16ToShort(cbDop); } + + + SVBT32 fcSttbfAssoc;// 0x10c offset to STTBF of associated strings. See STTBFASSOC. + ULONG fcSttbfAssocGet() { + return SVBT32ToUInt32(fcSttbfAssoc); } + SVBT16 cbSttbfAssoc;// 0x110 + USHORT cbSttbfAssocGet() { + return SVBT16ToShort(cbSttbfAssoc); } + + SVBT32 fcClx;// 0x112 file offset of beginning of information for complex files. + ULONG fcClxGet() { + return SVBT32ToUInt32(fcClx); } + SVBT16 cbClx;// 0x116 count of bytes of complex file information. 0 if file is non-complex. + USHORT cbClxGet() { + return SVBT16ToShort(cbClx); } + + SVBT32 fcPlcfpgdFtn;// 0x118 file offset of page descriptor PLC for footnote subdocument. + ULONG fcPlcfpgdFtnGet() { + return SVBT32ToUInt32(fcPlcfpgdFtn); } + SVBT16 cbPlcfpgdFtn;// 0x11C count of bytes of page descriptor PLC for footnote subdocument. + USHORT cbPlcfpgdFtnGet() { + return SVBT16ToShort(cbPlcfpgdFtn); } + // ==0 if document has not been paginated. The length of the PGD is 8 bytes. + + SVBT32 fcSpare1;// 0x11e file offset of the name of the original file. + ULONG fcSpare1Get() { + return SVBT32ToUInt32(fcSpare1); } + SVBT16 cbSpare1;// 0x122 count of bytes of the name of the original file. + USHORT cbSpare1Get() { + return SVBT16ToShort(cbSpare1); } + SVBT32 fcSpare2;// 0x124 file offset of the name of the original file. + ULONG fcSpare2Get() { + return SVBT32ToUInt32(fcSpare2); } + SVBT16 cbSpare2;// 0x128 count of bytes of the name of the original file. + USHORT cbSpare2Get() { + return SVBT16ToShort(cbSpare2); } + SVBT32 fcSpare3;// 0x12a file offset of the name of the original file. + ULONG fcSpare3Get() { + return SVBT32ToUInt32(fcSpare3); } + SVBT16 cbSpare3;// 0x12e count of bytes of the name of the original file. + USHORT cbSpare3Get() { + return SVBT16ToShort(cbSpare3); } + SVBT32 fcSpare4;// 0x130 file offset of the name of the original file. + ULONG fcSpare4Get() { + return SVBT32ToUInt32(fcSpare4); } + SVBT16 cbSpare4;// 0x134 count of bytes of the name of the original file. + USHORT cbSpare4Get() { + return SVBT16ToShort(cbSpare4); } + + SVBT16 cpnBteChp;// 0x18E count of CHPX FKPs recorded in file. In non-complex files if the number of + USHORT cpnBteChpGet() { + return SVBT16ToShort(cpnBteChp); } + // entries in the plcfbteChpx is less than this, the plcfbteChpx is incomplete. + SVBT16 cpnBtePap;// 0x190 count of PAPX FKPs recorded in file. In non-complex files if the number of + USHORT cpnBtePapGet() { + return SVBT16ToShort(cpnBtePap); } + // entries in the plcfbtePapx is less than this, the plcfbtePapx is incomplete. +}; + +struct W1_DOP ///////////////////////////////////// Document Properties +{ + SVBT16 fFlags; + USHORT fFlagsGet() { + return SVBT16ToShort(fFlags); } + // SVBT16 fFacingPages : 1;// 1 when facing pages should be printed + BOOL fFacingPagesGet() { + return 0 != ((fFlagsGet() >> 0) & 1); } + // SVBT16 fWidowControl : 1;// 1 when widow control is in effect. 0 when widow control disabled. + BOOL fWidowControlGet() { + return 0 != ((fFlagsGet() >> 1) & 1); } + // SVBT16 : 3;// unused + // SVBT16 fpc : 2;// 1 footnote position code: 0 as endnotes, 1 at bottom of page, 2 immediately beneath text + USHORT fpcGet() { + return (USHORT)((fFlagsGet() >> 5) & 3); } + // SVBT16 fWide : 1;// Landscape + BOOL fWideGet() { + return 0 != ((fFlagsGet() >> 7) & 1); } + // SVBT16 grpfIhdt : 8;// 0 specification of document headers and footers. See explanation under Headers and Footers topic. + USHORT grpfIhdtGet() { + return (USHORT)((fFlagsGet() >> 8) & 0xff); } + SVBT16 fFtnFlags; + USHORT fFtnFlagsGet() { + return SVBT16ToShort(fFtnFlags); } + // SVBT16 fFtnRestart : 1; + BOOL fFtnRestartGet() { + return 0 != ((fFtnFlagsGet() >> 0) & 1); } + // SVBT16 nFtn : 15;// 1 initial footnote number for document + USHORT nFtnGet() { + return (USHORT)((fFtnFlagsGet() >> 1) & 0x7fff); } + SVBT16 fRvsFlags; + USHORT fRvsFlagsGet() { + return SVBT16ToShort(fRvsFlags); } + // SVBT16 irmBar : 8; + USHORT irmBarGet() { + return (USHORT)((fRvsFlagsGet() >> 0) & 0xff); } + // SVBT16 irmProps : 7; + USHORT irmPropsGet() { + return (USHORT)((fRvsFlagsGet() >> 8) & 0x7f); } + // SVBT16 fRevMarking : 1;// when 1, Word will mark revisions as the document is edited + BOOL fRevMarkingGet() { + return 0 != ((fRvsFlagsGet() >> 15) & 1); } + SVBT16 fSveFlags; + USHORT fSveFlagsGet() { + return SVBT16ToShort(fSveFlags); } + // SVBT16 fBackup : 1;// always make backup when document saved when 1. + BOOL fBackupGet() { + return 0 != ((fSveFlagsGet() >> 0) & 1); } + // SVBT16 fExactCWords : 1; + BOOL fExactCWordsGet() { + return 0 != ((fSveFlagsGet() >> 1) & 1); } + // SVBT16 fPagHidden : 1;// + BOOL fPagHiddenGet() { + return 0 != ((fSveFlagsGet() >> 2) & 1); } + // SVBT16 fPagResults : 1; + BOOL fPagResultsGet() { + return 0 != ((fSveFlagsGet() >> 3) & 1); } + // SVBT16 fLockAtn : 1;// when 1, annotations are locked for editing + BOOL fLockAtnGet() { + return 0 != ((fSveFlagsGet() >> 4) & 1); } + // SVBT16 fMirrorMargins : 1;// swap margins on left/right pages when 1. + BOOL fMirrorMarginsGet() { + return 0 != ((fSveFlagsGet() >> 5) & 1); } + // SVBT16 : 10;// unused + SVBT16 fSpares; + USHORT fSparesGet() { + return SVBT16ToShort(fSpares); } + SVBT16 yaPage; + USHORT yaPageGet() { + return SVBT16ToShort(yaPage); } + SVBT16 xaPage; + USHORT xaPageGet() { + return SVBT16ToShort(xaPage); } + SVBT16 dyaTop; + USHORT dyaTopGet() { + return SVBT16ToShort(dyaTop); } + SVBT16 dxaLeft; + USHORT dxaLeftGet() { + return SVBT16ToShort(dxaLeft); } + SVBT16 dyaBottom; + USHORT dyaBottomGet() { + return SVBT16ToShort(dyaBottom); } + SVBT16 dxaRight; + USHORT dxaRightGet() { + return SVBT16ToShort(dxaRight); } + SVBT16 dxaGutter; + USHORT dxaGutterGet() { + return SVBT16ToShort(dxaGutter); } + SVBT16 dxaTab;// 720 twips default tab width + USHORT dxaTabGet() { + return SVBT16ToShort(dxaTab); } + SVBT16 wSpare;// + USHORT wSpareGet() { + return SVBT16ToShort(wSpare); } + SVBT16 dxaHotZ;// width of hyphenation hot zone measured in twips + USHORT dxaHotZGet() { + return SVBT16ToShort(dxaHotZ); } + SVBT16 rgwSpare[2];// reserved + SVBT32 dttmCreated;// DTTM date and time document was created + ULONG dttmCreatedGet() { + return SVBT32ToUInt32(dttmCreated); } + SVBT32 dttmRevised;// DTTM date and time document was last revised + ULONG dttmRevisedGet() { + return SVBT32ToUInt32(dttmRevised); } + SVBT32 dttmLastPrint;// DTTM date and time document was last printed + ULONG dttmLastPrintGet() { + return SVBT32ToUInt32(dttmLastPrint); } + SVBT16 nRevision;// number of times document has been revised since its creation + USHORT nRevisionGet() { + return SVBT16ToShort(nRevision); } + SVBT32 tmEdited;// time document was last edited + ULONG tmEditedGet() { + return SVBT32ToUInt32(tmEdited); } + SVBT32 cWords;// count of words tallied by last Word Count execution + ULONG cWordsGet() { + return SVBT32ToUInt32(cWords); } + SVBT32 cCh;// count of characters tallied by last Word Count execution + ULONG cChGet() { + return SVBT32ToUInt32(cCh); } + SVBT16 cPg;// count of pages tallied by last Word Count execution + USHORT cPgGet() { + return SVBT16ToShort(cPg); } + SVBT16 rgwSpareDocSum[2]; +}; +// cbDOP is 66. + +struct W1_CHP ///////////////////////////////////////////////////////// +{ + SVBT16 fChar; + SVBT16 ftc;// Font Code + SVBT8 hps;// Font size in half points + SVBT8 hpsPos;// Sub/Superscript ( signed number, 0 = normal ) + SVBT16 fText; + SVBT32 fcPic;// not stored in File + SVBT8 fnPic;// internal + SVBT16 hpsLargeChp;// ??? + + W1_CHP() { memset( this, 0, sizeof( *this)); } + + USHORT fCharGet() { return SVBT16ToShort(fChar); } + void fCharSet(USHORT n) { ShortToSVBT16(n, fChar); } + BOOL fBoldGet() { return 0 != ((fCharGet() >> 0) & 1); } + void fBoldSet(BOOL b) { fCharSet( ( fCharGet() & 0xfffe ) | ( b << 0 ) ); } + BOOL fItalicGet() { return 0 != ((fCharGet() >> 1) & 1); } + void fItalicSet(BOOL b) { fCharSet( ( fCharGet() & 0xfffd ) | ( b << 1 ) ); } + BOOL fStrikeGet() { return 0 != ((fCharGet() >> 2) & 1); } + BOOL fOutlineGet() { return 0 != ((fCharGet() >> 3) & 1); } + BOOL fFldVanishGet() { return 0 != ((fCharGet() >> 4) & 1); } + BOOL fSmallCapsGet() { return 0 != ((fCharGet() >> 5) & 1); } + BOOL fCapsGet() { return 0 != ((fCharGet() >> 6) & 1); } + BOOL fVanishGet() { return 0 != ((fCharGet() >> 7) & 1); } + BOOL fRMarkGet() { return 0 != ((fCharGet() >> 8) & 1); } + BOOL fSpecGet() { return 0 != ((fCharGet() >> 9) & 1); } + BOOL fsIcoGet() { return 0 != ((fCharGet() >> 10) & 1); } + BOOL fsFtcGet() { return 0 != ((fCharGet() >> 11) & 1); } + void fsFtcSet(BOOL b) { fCharSet( ( fCharGet() & 0xf7ff ) | ( b << 11 ) ); } + BOOL fsHpsGet() { return 0 != ((fCharGet() >> 12) & 1); } + void fsHpsSet(BOOL b) { fCharSet( ( fCharGet() & 0xefff ) | ( b << 12 ) ); } + BOOL fsKulGet() { return 0 != ((fCharGet() >> 13) & 1); } + void fsKulSet(BOOL b) { fCharSet( ( fCharGet() & 0xdfff ) | ( b << 13 ) ); } + BOOL fsPosGet() { return 0 != ((fCharGet() >> 14) & 1); } + BOOL fsSpaceGet() { return 0 != ((fCharGet() >> 15) & 1); } + // SVBT16 fBold :1;// 1 == opposite boldness of style + // SVBT16 fItalic :1;// 1 == opposite of style + // SVBT16 fStrike :1;// 1 == opposite of style + // SVBT16 fOutline :1;// 1 == opposite of style + // SVBT16 fFldVanish :1;// 1 == opposite of style + // SVBT16 fSmallCaps :1;// 1 == opposite of style + // SVBT16 fCaps :1;// 1 == opposite of style + // SVBT16 fVanish :1;// 1 == opposite of style + // SVBT16 fRMark :1;// ??? + // SVBT16 fSpec :1;// 1 == opposite of style + // SVBT16 fsIco :1;// 1 == Color (ico) different to style + // SVBT16 fsFtc :1;// 1 == FontCode (ftc) different to style + // SVBT16 fsHps :1;// 1 == FontSize (hps) different to style + // SVBT16 fsKul :1;// 1 == Underline Code (kul) different to style + // SVBT16 fsPos :1;// 1 == Char position (hpsPos) different to style + // SVBT16 fsSpace :1;// 1 == Char Spacing (qpsSpace) different to style + + USHORT ftcGet() { return SVBT16ToShort(ftc); } + void ftcSet(USHORT n) { ShortToSVBT16(n, ftc); } + void hpsSet(BYTE n) { ByteToSVBT8(n, hps); } + BYTE hpsGet() { return SVBT8ToByte(hps); } + + BYTE hpsPosGet() { return SVBT8ToByte(hpsPos); } + USHORT fTextGet() { return SVBT16ToShort(fText); } + void fTextSet(USHORT n) { ShortToSVBT16(n, fText); } + USHORT qpsSpaceGet() { return (USHORT)((fTextGet() >> 0) & 0x3f); } + USHORT wSpare2Get() { return (USHORT)((fTextGet() >> 6) & 3); } + USHORT icoGet() { return (USHORT)((fTextGet() >> 8) & 0xf); } + USHORT kulGet() { return (USHORT)((fTextGet() >> 12) & 7); } + void kulSet(USHORT n) { fTextSet( ( fTextGet() & 0x8fff ) | ( ( n & 7 ) << 12 ) ); } + BOOL fSysVanishGet() { return 0 != ((fTextGet() >> 15) & 1); } + // SVBT16 qpsSpace :6;// Char Spacing, -7 .. 56; 57 = -7, 63 = -1 + // SVBT16 wSpare2 : 2;// reserved + // SVBT16 ico :4;// color of Text: 0=black, 1=blue, 2=cyan, 3=green, 4=magenta, 5=red, 6=yellow, 7=white + // SVBT16 kul: 3;// Underline code: 0=none, 1=single, 2=by word, 3=double, 4=dotted + // SVBT16 fSysVanish: 1;// used internally + + ULONG fcPicGet() { return SVBT32ToUInt32(fcPic); } + USHORT fnPicGet() { return SVBT8ToByte(fnPic); } + USHORT hpsLargeChpGet() { return SVBT16ToShort(hpsLargeChp); } + + void Out(Ww1Shell&, Ww1Manager&); +}; + +struct W1_FFN ///////////////////////////////////////// Font Descriptor +{ + SVBT8 cbFfnM1;// 0x0 total length of FFN - 1. + USHORT cbFfnM1Get() { + return SVBT8ToByte(cbFfnM1); } + SVBT8 fFlags; + USHORT fFlagsGet() { + return SVBT8ToByte(fFlags); } + // SVBT8 prg : 2;// 0x1:03 pitch request + USHORT prgGet() { + return (USHORT)((fFlagsGet() >> 0) & 3); } + // SVBT8 fTrueType : 1;// 0x1:04 when 1, font is a TrueType font + BOOL fTrueTypeGet() { + return 0 != ((fFlagsGet() >> 2) & 1); } + // SVBT8 : 1;// 0x1:08 reserved + // SVBT8 ff : 3;// 0x1:70 font family id + USHORT ffGet() { + return (USHORT)((fFlagsGet() >> 4) & 7); } + // SVBT8 : 1;// 0x1:80 reserved + BYTE szFfn[65];// 0x6 zero terminated string that records name of font. + // Vorsicht: Dieses Array kann auch kleiner sein!!! + // Possibly followed by a second sz which records the name of an + // alternate font to use if the first named font does not exist + // on this system. Maximal size of szFfn is 65 characters. + BYTE* szFfnGet() { return szFfn; } +}; + +struct W1_PHE /////////////////////////////////////// Paragraph Height +{ + SVBT16 fFlags; + USHORT fFlagsGet() { + return SVBT16ToShort(fFlags); } + BOOL fSpareGet() { + return 0 != (fFlagsGet() & 1); } + BOOL fUnkGet() { + return 0 != ((fFlagsGet() >> 1) & 1); } + BOOL fDiffLinesGet() { + return 0 != ((fFlagsGet() >> 2) & 1); } + BYTE clMacGet() { + return sal::static_int_cast< sal_uInt8, sal_uInt16 >((fFlagsGet() >> 8) & 0xff); } + SVBT16 dxaCol; + USHORT dxaColGet() { + return SVBT16ToShort(dxaCol); } + SVBT16 xxx; // beachte die dreifachnutzung.... siehe doc. + USHORT dylHeightGet() { + return SVBT16ToShort(xxx); } + USHORT dylLineGet() { + return SVBT16ToShort(xxx); } + USHORT fStyleDirtyGet() { + return SVBT16ToShort(xxx); } +}; + +struct W1_PAPX ///////////////////////// Paragraph Property Difference +{ + SVBT8 stc; + BYTE stcGet() { + return SVBT8ToByte(stc); } + W1_PHE phe; + BYTE grpprl[1]; + BYTE* grpprlGet() { + return grpprl; } +}; + +struct W1_BRC //////////////////////////////////////////// Border Code +{ + SVBT16 aBits; + USHORT aBitsGet() { + return SVBT16ToShort(aBits); } + // SVBT16 dxpLineWidth : 3;// 0007 When dxpLineWidth is 0, 1, 2, 3, 4, or 5, + // this field is the width of a single line of border + // in units of 0.75 points Must be nonzero when brcType + // is nonzero. 6 == dotted, 7 == dashed. + BYTE dxpLineWidthGet() { + return sal::static_int_cast< sal_uInt8, sal_uInt16 >((aBitsGet() >> 0) & 0x0007); } + // SVBT16 brcType : 2;// 0018 border type code: 0 == none, 1 == single, 2 == thick, + // 3 == double + BYTE brcTypeGet() { + return sal::static_int_cast< sal_uInt8, sal_uInt16 >((aBitsGet() >> 3) & 0x0003); } + // SVBT16 fShadow : 1;// 0020 when 1, border is drawn with shadow. Must be 0 + // when BRC is a substructure of the TC + BYTE fShadowGet() { + return sal::static_int_cast< sal_uInt8, sal_uInt16 >((aBitsGet() >> 5) & 0x0001); } + // SVBT16 ico : 5;// 07C0 color code (see chp.ico) + BYTE icoGet() { + return sal::static_int_cast< sal_uInt8, sal_uInt16 >((aBitsGet() >> 6) & 0x001f); } + // SVBT16 dxpSpace : 5;// F800 width of space to maintain between border and + // text within border. Must be 0 when BRC is a + // substructure of the TC. Stored in points for Windows. + BYTE dxpSpaceGet() { + return sal::static_int_cast< sal_uInt8, sal_uInt16 >((aBitsGet() >> 11) & 0x001f); } +}; + +struct W1_BRC10 ///////////////////////////////// Border Code Word 1.0 +{ + SVBT16 aBits; + USHORT aBitsGet() { + return SVBT16ToShort(aBits); } + BYTE dxpLine2WidthGet() { + return sal::static_int_cast< sal_uInt8, sal_uInt16 >((aBitsGet() >> 0) & 0x0007); } + BYTE dxpSpaceBetweenGet() { + return sal::static_int_cast< sal_uInt8, sal_uInt16 >((aBitsGet() >> 3) & 0x0007); } + BYTE dxpLine1WidthGet() { + return sal::static_int_cast< sal_uInt8, sal_uInt16 >((aBitsGet() >> 6) & 0x0007); } + BYTE dxpSpaceGet() { + return sal::static_int_cast< sal_uInt8, sal_uInt16 >((aBitsGet() >> 9) & 0x001f); } + BYTE fShadowGet() { + return sal::static_int_cast< sal_uInt8, sal_uInt16 >((aBitsGet() >> 14) & 0x0001); } + BYTE fSpareGet() { + return sal::static_int_cast< sal_uInt8, sal_uInt16 >((aBitsGet() >> 15) & 0x0001); } +}; + +struct W1_FLD //////////////////////////////////////// FieldDescriptor +{ + SVBT8 ch; // boundary-type (begin(19), separator (20), end (21)) + BYTE chGet() { + return SVBT8ToByte(ch); } + SVBT8 flt; // field type / flags + BYTE fltGet() { + return SVBT8ToByte(flt); } + // variant, when ch==21: + BOOL fDifferGet() { + return (fltGet() >> 0) & 1; } + BOOL fResultDirtyGet() { + return (fltGet() >> 2) & 1; } + BOOL ResultEditedGet() { + return (fltGet() >> 3) & 1; } + BOOL fLockedGet() { + return (fltGet() >> 4) & 1; } + BOOL fPrivateResultGet() { + return (fltGet() >> 5) & 1; } + BOOL fNestedGet() { + return (fltGet() >> 6) & 1; } +}; + +struct W1_PIC /////////////////////////////////////// PictureStructure +{ + SVBT32 lcb;// 0x0 number of bytes in the PIC structure plus size of following picture data which may be a Window's metafile, a bitmap, or the filename of a TIFF file. + ULONG lcbGet() { + return SVBT32ToUInt32(lcb); } + SVBT16 cbHeader;// 0x4 number of bytes in the PIC (to allow for future expansion). + USHORT cbHeaderGet() { + return SVBT16ToShort(cbHeader); } + struct MFP { + SVBT16 mm;// 0x6 int + USHORT mmGet() { + return SVBT16ToShort(mm); } + SVBT16 xExt;// 0x8 int + USHORT xExtGet() { + return SVBT16ToShort(xExt); } + SVBT16 yExt;// 0xa int + USHORT yExtGet() { + return SVBT16ToShort(yExt); } + SVBT16 hMF;// 0xc int + USHORT hMFGet() { + return SVBT16ToShort(hMF); } + } mfp; + union W1_MFP_BMP { + SVBT8 bm[14];// 0xe BITMAP(14 bytes) Window's bitmap structure when PIC describes a BITMAP. + SVBT8 rcWinMF[14];// 0xe rc (rectangle - 8 bytes) rect for window origin and extents when metafile is stored -- ignored if 0 + } MFP_BMP; + SVBT16 dxaGoal;// 0x1c horizontal measurement in twips of the rectangle the picture should be imaged within. + USHORT dxaGoalGet() { + return SVBT16ToShort(dxaGoal); } + SVBT16 dyaGoal;// 0x1e vertical measurement in twips of the rectangle the picture should be imaged within. + USHORT dyaGoalGet() { + return SVBT16ToShort(dyaGoal); } + SVBT16 mx;// 0x20 horizontal scaling factor supplied by user in .1% units. + USHORT mxGet() { + return SVBT16ToShort(mx); } + SVBT16 my;// 0x22 vertical scaling factor supplied by user in .1% units. + USHORT myGet() { + return SVBT16ToShort(my); } + SVBT16 dxaCropLeft;// 0x24 the amount the picture has been cropped on the left in twips. + USHORT dxaCropLeftGet() { + return SVBT16ToShort(dxaCropLeft); } + SVBT16 dyaCropTop;// 0x26 the amount the picture has been cropped on the top in twips. + USHORT dyaCropTopGet() { + return SVBT16ToShort(dyaCropTop); } + SVBT16 dxaCropRight;// 0x28 the amount the picture has been cropped on the right in twips. + USHORT dxaCropRightGet() { + return SVBT16ToShort(dxaCropRight); } + SVBT16 dyaCropBottom;// 0x2a the amount the picture has been cropped on the bottom in twips. + USHORT dyaCropBottomGet() { + return SVBT16ToShort(dyaCropBottom); } + SVBT16 flags; + USHORT flagsGet() { + return SVBT16ToShort(flags); } +// brcl : 4;// 000F Obsolete, superseded by brcTop, etc. In + BYTE brclGet() { + return sal::static_int_cast< BYTE, sal_uInt16 >(flagsGet() & 0xf); } +// fFrameEmpty : 1;// 0010 picture consists of a single frame + BOOL fFrameEmptyGet() { + return sal::static_int_cast< BYTE, sal_uInt16 >((flagsGet() >> 4) & 1); } +// win6 stuff: +// fBitmap : 1;// 0020 ==1, when picture is just a bitmap +// BOOL fBitmapGet() { +// return (flagsGet() >> 5) & 1; } +// fDrawHatch : 1;// 0040 ==1, when picture is an active OLE object +// BOOL fDrawHatchGet() { +// return (flagsGet() >> 6) & 1; } +// fError : 1;// 0080 ==1, when picture is just an error message +// BOOL fErrorGet() { +// return (flagsGet() >> 7) & 1; } +// bpp : 8;// FF00 bits per pixel, 0 = unknown +// BYTE bppGet() { +// return (flagsGet() >> 8) & 0xff; } +// SVBT16 rgbrc[4]; +// USHORT rgbrcGet(USHORT nIndex) { +// return SVBT16ToShort(rgbrc[nIndex]); } +// W1_BRC brcTop;// 0x2e specification for border above picture +// W1_BRC brcLeft;// 0x30 specification for border to the left +// W1_BRC brcBottom;// 0x32 specification for border below picture +// W1_BRC brcRight;// 0x34 specification for border to the right +// SVBT16 dxaOrigin;// 0x36 horizontal offset of hand annotation origin +// USHORT dxaOriginGet() { +// return SVBT16ToShort(dxaOrigin); } +// SVBT16 dyaOrigin;// 0x38 vertical offset of hand annotation origin +// USHORT dyaOriginGet() { +// return SVBT16ToShort(dyaOrigin); } + SVBT8 rgb;// 0x3a variable array of bytes containing Window's metafile, bitmap or TIFF file filename. + BYTE* rgbGet() { + return rgb; } +}; + +struct W1_TBD ///////////////////////////////////////////////////////// +{ + SVBT8 aBits1; + BYTE aBits1Get() { + return SVBT8ToByte(aBits1); } +// SVBT8 jc : 3;// 0x07 justification code: 0=left tab, 1=centered tab, 2=right tab, 3=decimal tab, 4=bar + BYTE jcGet() { + return aBits1Get() & 0x07; } +// SVBT8 tlc : 3;// 0x38 tab leader code: 0=no leader, 1=dotted leader, + // 2=hyphenated leader, 3=single line leader, 4=heavy line leader + BYTE tlcGet() { + return (aBits1Get() >> 3 ) & 0x07; } +// * int :2 C0 reserved +}; + +struct W1_TC ////////////////////////////////////////////////////////// +{ + SVBT8 aBits1; + BYTE aBits1Get() { + return SVBT8ToByte(aBits1); } + BYTE fFirstMergedGet() { + return aBits1Get() & 0x01; } + BYTE fMergedGet() { + return (aBits1Get() >> 1 ) & 0x01; } + SVBT8 aBits2; +// SVBT16 fFirstMerged : 1;// 0001 set to 1 when cell is first cell of a range of cells that have been merged. +// SVBT16 fMerged : 1;// 0002 set to 1 when cell has been merged with preceding cell. +// SVBT16 fUnused : 14;// FFFC reserved + W1_BRC10 rgbrc[4];// notational convenience for referring to brcTop, brcLeft, etc fields. + W1_BRC10* rgbrcGet() { + return rgbrc; } +// BRC brcTop;// specification of the top border of a table cell +// BRC brcLeft;// specification of left border of table row +// BRC brcBottom;// specification of bottom border of table row +// BRC brcRight;// specification of right border of table row. +}; +// cbTC (count of bytes of a TC) is 10(decimal), A(hex). + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |