diff options
Diffstat (limited to 'sw/source/filter/ww1/fltshell.cxx')
-rw-r--r-- | sw/source/filter/ww1/fltshell.cxx | 2088 |
1 files changed, 2088 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..2cf1ca325a5b --- /dev/null +++ b/sw/source/filter/ww1/fltshell.cxx @@ -0,0 +1,2088 @@ +/************************************************************************* + * + * 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); + ASSERT(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 + ASSERT( 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() +{ + ASSERT(!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++; + ASSERT( pEntry->nMkCntnt + <= pDoc->GetNodes()[nPosNd]->GetCntntNode()->Len(), + "Attribut-Anfang hinter Zeilenende" ); + } + if(( pEntry->nPtNode.GetIndex() + 1 == nPosNd ) + &&( pEntry->nPtCntnt >= nPosCt )){ + pEntry->nPtCntnt++; + ASSERT( 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) +{ + ASSERT(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 ) +{ + ASSERT(!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(); +// BOOL b1 = rNds[rRegion.GetPoint()->nNode]->FindTableNode() != 0; +// const SwStartNode* p1 = rNds[rRegion.GetPoint()->nNode]->FindTableBoxStartNode(); +// const SwStartNode* p2 = rNds[rRegion.GetMark()->nNode]->FindTableBoxStartNode(); + 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 = rPaM.GetCntntNode(); + 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. + ASSERT(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 ) +{ + ASSERT(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 ) +{ + ASSERT( 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 + { + ASSERT( 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: + ASSERT( 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) +{ + ASSERT(FALSE, "GetCellAttr ausserhalb von normalem Text"); + return GetDoc().GetAttrPool().GetDefaultItem(nWhich); +} + +BOOL SwFltOutBase::BeginTable() +{ + ASSERT(FALSE, "BeginTable ausserhalb von normalem Text"); + return FALSE; +} + +void SwFltOutBase::NextTableCell() +{ + ASSERT(FALSE, "NextTableCell ausserhalb von normalem Text"); +} + +void SwFltOutBase::NextTableRow() +{ + ASSERT(FALSE, "NextTableRow ausserhalb von normalem Text"); +} + +void SwFltOutBase::SetTableWidth(SwTwips /*nW*/) +{ + ASSERT(FALSE, "SetTableWidth ausserhalb von normalem Text"); +} + +void SwFltOutBase::SetTableOrient(sal_Int16 /*eOri*/) +{ + ASSERT(FALSE, "SetTableOrient ausserhalb von normalem Text"); +} + +void SwFltOutBase::SetCellWidth(SwTwips /*nWidth*/, USHORT /*nCell*/) +{ + ASSERT(FALSE, "SetCellWidth ausserhalb von normalem Text"); +} + +void SwFltOutBase::SetCellHeight(SwTwips /*nH*/) +{ + ASSERT(FALSE, "SetCellHeight ausserhalb von normalem Text"); +} + +void SwFltOutBase::SetCellBorder(const SvxBoxItem& /*rFmtBox*/, USHORT /*nCell*/) +{ + ASSERT(FALSE, "SetCellBorder ausserhalb von normalem Text"); +} + +void SwFltOutBase::SetCellSpace(USHORT /*nSp*/) +{ + ASSERT(FALSE, "SetCellSpace ausserhalb von normalem Text"); +} + +void SwFltOutBase::DeleteCell(USHORT /*nCell*/) +{ + ASSERT(FALSE, "DeleteCell ausserhalb von normalem Text"); +} + +void SwFltOutBase::EndTable() +{ + ASSERT(FALSE, "EndTable ausserhalb von normalem Text"); +} + +/*virtual*/ BOOL SwFltOutDoc::IsInTable() +{ + return pTable != 0; +}; + +BOOL SwFltOutDoc::BeginTable() +{ + if(bReadNoTbl) + return FALSE; + + if (pTable){ + ASSERT(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: + ASSERT(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){ + ASSERT(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){ + ASSERT(FALSE, "SwFltOutDoc:GetBox:pTableLines"); + return 0; + } + if( ny >= pTableLines->Count() ){ // Notbremse + ASSERT( FALSE, "SwFltOutDoc:GetBox:ny >= Count()"); + ny = pTableLines->Count() - 1; + } + SwTableLine* pTableLine = (*pTableLines)[ny]; + if(!pTableLine){ + ASSERT(FALSE, "SwFltOutDoc:GetBox:pTableLine"); + return 0; + } + SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes(); + if(!pTableBoxes){ + ASSERT(FALSE, "SwFltOutDoc:GetBox:pTableBoxes"); + return 0; + } + if( nx >= pTableBoxes->Count() ){ // Notbremse + ASSERT(FALSE, "SwFltOutDoc:GetBox:nx >= Count()"); + nx = pTableBoxes->Count() - 1; + } + SwTableBox* pTableBox = (*pTableBoxes)[nx]; + + ASSERT(pTableBox != 0, "SwFltOutDoc:GetBox:pTableBox"); + return pTableBox; +} + +void SwFltOutDoc::NextTableCell() +{ + if(!pTable){ + ASSERT(pTable, "NextTableCell ohne Tabelle"); + return; + } + const SwTableLines* pTableLines = &pTable->GetTabLines(); + SwTableLine* pTableLine = (*pTableLines)[usTableY]; + SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes(); + SwTableBox* pTableBox = (*pTableBoxes)[usTableX]; + ASSERT(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]; + ASSERT(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){ + ASSERT(pTable, "SetTableWidth ohne Tabelle"); + return; + } + ASSERT( 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){ + ASSERT(pTable, "SetTableOrient ohne Tabelle"); + return; + } + pTable->GetFrmFmt()->SetFmtAttr( SwFmtHoriOrient( 0, eOri )); +} + +void SwFltOutDoc::SetCellWidth(SwTwips nWidth, USHORT nCell /* = USHRT_MAX */ ) +{ + if(!pTable){ + ASSERT(pTable, "SetCellWidth ohne Tabelle"); + return; + } + ASSERT( 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){ + ASSERT(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){ + ASSERT(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){ + ASSERT(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) + { + ASSERT(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){ + ASSERT(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()) + { + ASSERT((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() ) + { + ASSERT(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* +#ifdef DBG_UTIL + pMoreAttrs /*= 0*/ +#endif + ) +{ + ASSERT(!pMoreAttrs, "SwFltOutBase:BeginFly mit pMoreAttrs" ); + eFlyAnchor = eAnchor; + bFlyAbsPos = bAbsolutePos; // Bloedsinn eigentlich + return TRUE; +} + +/*virtual*/ void SwFltOutBase::SetFlyAnchor( RndStdIds eAnchor ) +{ + if( !IsInFly() ){ + ASSERT( FALSE, "SetFlyAnchor() ohne Fly" ); + return; + } + if ( eAnchor == FLY_AS_CHAR ){ + ASSERT( 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 /*= FLY_AT_PARA*/, + BOOL bAbsolutePos /*= FALSE*/, + const SfxItemSet* pMoreAttrs /*= 0*/ ) + +{ + 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: + ASSERT(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 +// aStack.NewAttr( *pPaM->GetPoint(), SwFltAnchor( pFly ) ); + + pSet->Put( aAnchor ); + SwFrmFmt* pF = MakeFly( eAnchor, pSet ); + delete pSet; + +// set pam in Fly + const SwFmtCntnt& rCntnt = pF->GetCntnt(); + ASSERT( 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{ + ASSERT(pFly, "SetFlyAttr ohne Doc-Fly"); + return; + } +} + +/*virtual*/ const SfxPoolItem& SwFltOutDoc::GetFlyFrmAttr(USHORT nWhich) +{ + if (pFly){ + return pFly->GetFmtAttr( nWhich ); + }else{ + ASSERT(pFly, "GetFlyAttr ohne Fly"); + return GetDoc().GetAttrPool().GetDefaultItem(nWhich); + } +} + +void SwFltOutDoc::EndFly() +{ + if( pTable ){ + ASSERT( 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) +{ +// ASSERT( pFlyAttrs, "GetFlyFrmAttr ohne Coll-FlyAttrs" ); + if( pFlyAttrs ) + return pFlyAttrs->Get( nWhich, FALSE ); + else + return GetDoc().GetAttrPool().GetDefaultItem(nWhich); +} + +BOOL SwFltFormatCollection::BeginFly( RndStdIds eAnchor /*= FLY_AT_PARA*/, + BOOL bAbsolutePos /*= FALSE*/, + const SfxItemSet* pMoreAttrs /*= 0*/ ) + +{ + SwFltOutBase::BeginFly( eAnchor, bAbsolutePos, pMoreAttrs ); + bHasFly = TRUE; + return TRUE; +} + +void SwFltFormatCollection::EndFly() // Wird nie aufgerufen +{ +} + +BOOL SwFltFormatCollection::BeginStyleFly( SwFltOutDoc* pOutDoc ) +{ + ASSERT( pOutDoc, "BeginStyleFly ohne pOutDoc" ); + ASSERT( 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 /*= FLY_AT_PARA*/, + BOOL bAbsolutePos /*= FALSE*/ ) + +{ + if (pOut->IsInFly()){ + ASSERT(FALSE, "BeginFly in Fly"); + return FALSE; + } + if (pOutDoc->IsInTable()){ + ASSERT(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 /*= text::RelOrientation::FRAME*/, + sal_Int16 eHAlign /*= text::HoriOrientation::NONE*/ ) +{ + SetFlyFrmAttr( SwFmtHoriOrient( nXPos, eHAlign, eHRel ) ); +} + +void SwFltShell::SetFlyYPos( short nYPos, sal_Int16 eVRel /*= text::RelOrientation::FRAME*/, + sal_Int16 eVAlign /*= text::VertOrientation::NONE*/ ) +{ + SetFlyFrmAttr( SwFmtVertOrient( nYPos, eVAlign, eVRel ) ); +} + + +void SwFltShell::EndFly() +{ + if (!pOut->IsInFly()){ + ASSERT(FALSE, "EndFly ohne Fly"); + return; + } + if (pOutDoc->IsInTable()){ // Table verschraenkt mit Fly macht keinen Sinn + ASSERT(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 + ASSERT(FALSE, "Fussnote in Fly nicht erlaubt"); + return; + } + if( pOutDoc->IsInTable() ){ + ASSERT(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 ); +// aEndStack.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); + ASSERT(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 + ASSERT(pFN, "Probleme beim Anlegen des Fussnoten-Textes"); + return; + } + const SwNodeIndex* pStartIndex = ((SwTxtFtn*)pFN)->GetStartNode(); + ASSERT(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 ); +// aEndStack.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( + ); //(bUseLeft) ? &pCurrentPageDesc->GetLeft() : + SwFrmFmt* pHdFtFmt; + pFmt->SetFmtAttr(SwFmtHeader(TRUE)); + pHdFtFmt = (SwFrmFmt*)pFmt->GetHeader().GetHeaderFmt(); + const SwNodeIndex* pStartIndex = pHdFtFmt->GetCntnt().GetCntntIdx(); + if (!pStartIndex) + return; + ASSERT(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( + ); //(bUseLeft) ? &pCurrentPageDesc->GetLeft() : + SwFrmFmt* pHdFtFmt; + pFmt->SetFmtAttr(SwFmtFooter(TRUE)); + pHdFtFmt = (SwFrmFmt*)pFmt->GetFooter().GetFooterFmt(); + const SwNodeIndex* pStartIndex = pHdFtFmt->GetCntnt().GetCntntIdx(); + if (!pStartIndex) + return; + ASSERT(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) +{ + ASSERT(pColls[nWhich], "Next style for noexistent style" ); + ASSERT(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)); +} + +/* vi:set tabstop=4 shiftwidth=4 expandtab: */ |