blob: 0f4ef5c783113899897aae4951bb475d99998f6c [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the 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, sal_Bool bNext)
{
SwCntntNode * pCNd = rIdx.GetNode().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),
//Modify here for #119405, by easyfan, 2012-05-24
nPtNode(nMkNode),mnStartCP(-1),mnEndCP(-1),bIsParaEnd(false)
//End of modification, by easyfan
{
// Anfang vom Bereich merken
nMkCntnt = rStartPos.nContent.GetIndex();
pAttr = pHt; // speicher eine Kopie vom Attribut
bOld = sal_False; // used for marking Attributes *before* skipping field results
bLocked = sal_True; // locke das Attribut --> darf erst
bCopied = sal_False; // gesetzt werden, wenn es wieder geunlocked ist
bConsumedByField = sal_False;
}
SwFltStackEntry::SwFltStackEntry(const SwFltStackEntry& rEntry) :
nMkNode(rEntry.nMkNode),
nPtNode(rEntry.nPtNode)
{
pAttr = rEntry.pAttr->Clone();
nMkCntnt= rEntry.nMkCntnt;
bOld = rEntry.bOld;
bLocked = bCopied = sal_True; // when rEntry were NOT bLocked we would never have been called
bConsumedByField = rEntry.bConsumedByField;
//Modify here for #119405, by chengjh, 2012-08-16
mnStartCP= rEntry.mnStartCP;
mnEndCP = rEntry.mnEndCP;
bIsParaEnd = rEntry.bIsParaEnd;
//End
}
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 sal_uInt16'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 = sal_False; // freigeben und das ENDE merken
nPtNode = rEndPos.nNode.GetIndex()-1;
nPtCntnt = rEndPos.nContent.GetIndex();
}
//Modify here for #119405, by chengjh, 2012-08-16
//The only position of 0x0D will not be able to make regin in the old logic
//because it is beyond the length of para...need special consideration here.
bool SwFltStackEntry::IsAbleMakeRegion()
{
SwCntntNode *const pCntntNode( SwNodeIndex(nMkNode, +1).GetNode().GetCntntNode() );
if ( (nMkNode.GetIndex() == nPtNode.GetIndex())
&& (nMkCntnt == nPtCntnt)
&& ( (0 != nPtCntnt)
|| ( pCntntNode
&& ( 0 != pCntntNode->Len() ) ) )
&& ( RES_TXTATR_FIELD != pAttr->Which()
&& RES_TXTATR_ANNOTATION != pAttr->Which()
&& RES_TXTATR_INPUTFIELD != pAttr->Which() )
&& !( bIsParaEnd
&& pCntntNode
&& pCntntNode->IsTxtNode()
&& 0 != pCntntNode->Len() ) )
{
return false;
}
return true;
}
//End
sal_Bool SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, sal_Bool bCheck )
{
// does this range actually contain something?
// empty range is allowed if at start of empty paragraph
// fields are special: never have range, so leave them
//Modify here for #119405, by chengjh, 2012-08-16
//Revised the code and move the code segment to defined function
if ( !IsAbleMakeRegion() )
{
return sal_False;
}
//End
// !!! Die Content-Indizies beziehen sich immer auf den Node !!!
rRegion.GetPoint()->nNode = nMkNode.GetIndex() + 1;
SwCntntNode* pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, sal_True);
rRegion.GetPoint()->nContent.Assign(pCNd, nMkCntnt);
rRegion.SetMark();
if( nMkNode != nPtNode )
{
rRegion.GetPoint()->nNode = nPtNode.GetIndex() + 1;
pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, sal_False);
}
rRegion.GetPoint()->nContent.Assign(pCNd, nPtCntnt);
#if OSL_DEBUG_LEVEL > 1
ASSERT( CheckNodesRange( rRegion.Start()->nNode,
rRegion.End()->nNode, sal_True ),
"Attribut oder AEhnliches ueber Bereichs-Grenzen" );
#endif
if( bCheck )
return CheckNodesRange( rRegion.Start()->nNode,
rRegion.End()->nNode, sal_True );
else
return sal_True;
}
SwFltControlStack::SwFltControlStack(SwDoc* pDo, sal_uLong nFieldFl)
: nFieldFlags(nFieldFl), bHasSdOD(true)
,bSdODChecked(false), pDoc(pDo), bIsEndStack(false)
//End
{
}
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 )
{
sal_uInt16 nCnt = static_cast< sal_uInt16 >(Count());
SwFltStackEntry* pEntry;
sal_uLong nPosNd = rPos.nNode.GetIndex();
sal_uInt16 nPosCt = rPos.nContent.GetIndex() - 1;
for (sal_uInt16 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()
{
sal_uInt16 nCnt = static_cast< sal_uInt16 >(Count());
for (sal_uInt16 i=0; i < nCnt; i++)
(*this)[ i ]->bOld = sal_True;
}
void SwFltControlStack::NewAttr(const SwPosition& rPos, const SfxPoolItem & rAttr )
{
SwFltStackEntry *pTmp = new SwFltStackEntry(rPos, rAttr.Clone() );
//Modify here for #119405, by easyfan, 2012-05-24
pTmp->SetStartCP(GetCurrAttrCP());
//End of modification, by easyfan
sal_uInt16 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);
}
//Modify for #119405 by chengjh, 2012-08-16
//Clear the para end position recorded in reader intermittently for the least impact on loading performance
//Because the attributes handled based on the unit of para
if ( Count() == 0 )
{
ClearParaEndPosition();
bHasSdOD = true;
bSdODChecked = false;
}
//End
}
// 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, sal_uInt16 nAttrId /* = 0 */)
{
sal_uInt16 nCnt = static_cast< sal_uInt16 >(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 );
sal_uInt16 nAktIdx = pPos.nContent.GetIndex();
sal_uInt16 nCnt = static_cast< sal_uInt16 >(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, sal_uInt16 nAttrId,
sal_Bool bTstEnde, long nHand, sal_Bool consumedByField )
{
ASSERT(!nAttrId ||
(POOLATTR_BEGIN <= nAttrId && POOLATTR_END > nAttrId) ||
(RES_FLTRATTR_BEGIN <= nAttrId && RES_FLTRATTR_END > nAttrId),
"Falsche Id fuers Attribut")
sal_uInt16 nCnt = static_cast< sal_uInt16 >(Count());
SwFltStackEntry* pEntry;
for (sal_uInt16 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);
//Modify here for #119405, by easyfan, 2012-05-24
pEntry->SetEndCP(GetCurrAttrCP());
//End of modification, by easyfan
}
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, sal_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, sal_Bool bCheck )
{
if (pEntry->MakeRegion(pDoc, rRegion, bCheck )){
// sal_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 (rRegion.GetPoint()->nNode.GetNode().FindTableBoxStartNode()
!= rRegion.GetMark()->nNode.GetNode().FindTableBoxStartNode())
{
rRegion.Exchange(); // Ungueltiger Bereich
rRegion.DeleteMark(); // -> beide auf Mark
}
}else{
MakePoint(pEntry, pDoc, rRegion);
}
}
#if OSL_DEBUG_LEVEL > 1
extern sal_Bool CheckNodesRange( const SwNodeIndex& rStt,
const SwNodeIndex& rEnd, sal_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 sal_True fuer gueltigen Bereich
static sal_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 ?
}
//Modify for #119405 by chengjh, 2012-08-16
//***This function will check whether there is existing individual attribute positon for 0x0D***/
//The check will happen only once for a paragraph during loading
bool SwFltControlStack::HasSdOD()
{
sal_uInt16 nCnt = static_cast< sal_uInt16 >(Count());
SwFltStackEntry* pEntry = 0;
bool bRet = false;
for (sal_uInt16 i=0; i < nCnt; i++)
{
pEntry = (*this)[ i ];
if ( pEntry && pEntry->mnStartCP == pEntry->mnEndCP )
{
if ( CheckSdOD(pEntry->mnStartCP,pEntry->mnEndCP) )
{
bRet = true;
break;
}
}
}
return bRet;
}
//End
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->GetCurrentViewShell() //swmod 071108//swmod 071225
&& (FLY_AT_PARA == pFmt->GetAnchor().GetAnchorId()))
{
pFmt->MakeFrms();
}
}
}
break;
case RES_FLTR_STYLESHEET:
break;
case RES_TXTATR_FIELD:
case RES_TXTATR_ANNOTATION:
case RES_TXTATR_INPUTFIELD:
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, sal_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:
{
SwFltBookmark* pB = (SwFltBookmark*)pEntry->pAttr;
const String& rName = ((SwFltBookmark*)pEntry->pAttr)->GetName();
if (IsFlagSet(BOOK_TO_VAR_REF))
{
SwFieldType* pFT = pDoc->GetFldType(RES_SETEXPFLD, rName, false);
if (!pFT)
{
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 ( ( !IsFlagSet(HYPO) || IsFlagSet(BOOK_AND_REF) ) &&
!pEntry->bConsumedByField )
{
MakeBookRegionOrPoint(pEntry, pDoc, aRegion, sal_True);
// #120879# - create a cross reference heading bookmark if appropriate.
const IDocumentMarkAccess::MarkType eBookmarkType =
( pB->IsTOCBookmark() &&
IDocumentMarkAccess::IsLegalPaMForCrossRefHeadingBookmark( aRegion ) )
? IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK
: IDocumentMarkAccess::BOOKMARK;
pDoc->getIDocumentMarkAccess()->makeMark( aRegion, rName, eBookmarkType );
}
}
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, sal_False, &pItem ) )
{
aBkSet.Put( *pItem );
pNd->ResetAttr( RES_BREAK );
}
if( !pTOXAttr->HadPageDescItem()
&& SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, sal_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, sal_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:
{
//Modify here for #119405, by chengjh, 2012-08-16
//Revised for more complex situations should be considered
if ( !bSdODChecked )
{
bHasSdOD = HasSdOD();
bSdODChecked = true;
}
sal_Int32 nStart = pEntry->GetStartCP();
sal_Int32 nEnd = pEntry->GetEndCP();
if (nStart != -1 && nEnd != -1 && nEnd >= nStart )
{
pEntry->SetIsParaEnd( IsParaEndInCPs(nStart,nEnd,bHasSdOD) );
}
//End
if (pEntry->MakeRegion(pDoc, aRegion, sal_False))
{
//Modify here for #119405, by easyfan, 2012-05-24
//Refined 2012-08-16
if (pEntry->IsParaEnd())
{
pDoc->InsertPoolItem(aRegion, *pEntry->pAttr, 0,true);
}else
{
pDoc->InsertPoolItem(aRegion, *pEntry->pAttr, 0);
}
//End
}
}
break;
}
}
SfxPoolItem* SwFltControlStack::GetFmtStackAttr(sal_uInt16 nWhich, sal_uInt16 * pPos)
{
SwFltStackEntry* pEntry;
sal_uInt16 nSize = static_cast< sal_uInt16 >(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::GetOpenStackAttr(const SwPosition& rPos, sal_uInt16 nWhich)
{
SwFltStackEntry* pEntry;
sal_uInt16 nSize = static_cast< sal_uInt16 >(Count());
SwNodeIndex aAktNode( rPos.nNode, -1 );
sal_uInt16 nAktIdx = rPos.nContent.GetIndex();
while (nSize)
{
pEntry = (*this)[ --nSize ];
if( pEntry->bLocked
&& (pEntry->pAttr->Which() == nWhich)
&& (pEntry->nMkNode == aAktNode)
&& (pEntry->nMkCntnt == nAktIdx ))
{
return (SfxPoolItem*)pEntry->pAttr;
}
}
return 0;
}
const SfxPoolItem* SwFltControlStack::GetFmtAttr(const SwPosition& rPos, sal_uInt16 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 = rPos.nNode.GetNode().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);
sal_uInt16 nStartIdx = pStt->nContent.GetIndex();
SwNodeIndex aEndNode(pEnd->nNode, -1);
sal_uInt16 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 (sal_uInt16 nSize = static_cast< sal_uInt16 >(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(const SfxPoolItem *, const SfxPoolItem * pNew)
{
if (pNew->Which() == RES_FMT_CHG)
{
const SwFmtChg * pFmtChg = dynamic_cast<const 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, const bool bIsTOCBookmark )
: SfxPoolItem( RES_FLTR_BOOKMARK )
, mnHandle( nHand )
, maName( rNa )
, maVal( rVa )
, mbIsTOCBookmark( bIsTOCBookmark )
{
// 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 )
if ( IsTOCBookmark() )
{
maName = IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix();
maName += rNa;
}
}
SwFltBookmark::SwFltBookmark(const SwFltBookmark& rCpy)
: SfxPoolItem( RES_FLTR_BOOKMARK )
, mnHandle( rCpy.mnHandle )
, maName( rCpy.maName )
, maVal( rCpy.maVal )
, mbIsTOCBookmark( rCpy.mbIsTOCBookmark )
{
}
int SwFltBookmark::operator==(const SfxPoolItem& rItem) const
{
return ( maName == ((SwFltBookmark&)rItem).maName)
&& (mnHandle == ((SwFltBookmark&)rItem).mnHandle);
}
SfxPoolItem* SwFltBookmark::Clone(SfxItemPool*) const
{
return new SwFltBookmark(*this);
}
//------ hier stehen die Methoden von SwFltTOX -----------
SwFltTOX::SwFltTOX(SwTOXBase* pBase, sal_uInt16 _nCols)
: SfxPoolItem(RES_FLTR_TOX), pTOXBase(pBase), nCols( _nCols ),
bHadBreakItem( sal_False ), bHadPageDescItem( sal_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, sal_Bool bNew, sal_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(sal_False),
bProtect(sal_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();
sal_uInt16 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
sal_uLong nNd = pPos->nNode.GetIndex();
sal_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()
{
sal_uInt16 i;
if (eSubMode == Style)
EndStyle();
if( pOutDoc->IsInTable() ) // falls nicht ordentlich abgeschlossen
EndTable();
if( pOutDoc->IsInFly() )
EndFly();
GetDoc().SetUpdateExpFldStat(true);
GetDoc().SetInitDBFields(sal_True);
aStack.SetAttr(*pPaM->GetPoint(), 0, sal_False);
aStack.SetAttr(*pPaM->GetPoint(), 0, sal_False);
aEndStack.SetAttr(*pPaM->GetPoint(), 0, sal_False);
aEndStack.SetAttr(*pPaM->GetPoint(), 0, sal_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( sal_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 );
sal_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( sal_uInt16 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( sal_False, "Ungueltiger SwFltStyleCode" );
}
return *this;
}
SwFltShell& SwFltShell::operator << (SwFltBookmark& aBook)
{
ConvertUStr( aBook.maName );
aBook.maVal = QuoteStr(aBook.maVal);
aEndStack.NewAttr(*pPaM->GetPoint(), aBook);
return *this;
}
void SwFltShell::SetBookEnd(long nHandle)
{
aEndStack.SetAttr( *pPaM->GetPoint(), RES_FLTR_BOOKMARK, sal_True, nHandle );
}
SwFltShell& SwFltShell::EndItem( sal_uInt16 nAttrId )
{
switch( nAttrId )
{
case RES_FLTR_BOOKMARK:
ASSERT( sal_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(sal_uInt16 nWhich)
{
return *rStack.GetFmtAttr(*pPaM->GetPoint(), nWhich);
}
const SfxPoolItem& SwFltFormatCollection::GetAttr(sal_uInt16 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(sal_uInt16 nWhich)
{
SwCntntNode * pNd = pPaM->GetPoint()->nNode.GetNode().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(sal_uInt16 nWhich)
{
return GetColl()->GetFmtAttr(nWhich); // mit Parents
}
const SfxPoolItem& SwFltShell::GetNodeOrStyAttr(sal_uInt16 nWhich)
{
return pOut->GetNodeOrStyAttr( nWhich );
}
const SfxPoolItem& SwFltShell::GetAttr(sal_uInt16 nWhich)
{
return pOut->GetAttr( nWhich );
}
const SfxPoolItem& SwFltShell::GetFlyFrmAttr(sal_uInt16 nWhich)
{
return pOut->GetFlyFrmAttr( nWhich );
}
SwFieldType* SwFltShell::GetSysFldType(sal_uInt16 eWhich)
{
return GetDoc().GetSysFldType(eWhich);
}
sal_Bool SwFltShell::GetWeightBold()
{
return ((SvxWeightItem&)GetNodeOrStyAttr(RES_CHRATR_WEIGHT)).GetWeight()
!= WEIGHT_NORMAL;
}
sal_Bool SwFltShell::GetPostureItalic()
{
return ((SvxPostureItem&)GetNodeOrStyAttr(RES_CHRATR_POSTURE)).GetPosture()
!= ITALIC_NONE;
}
sal_Bool SwFltShell::GetCrossedOut()
{
return ((SvxCrossedOutItem&)GetNodeOrStyAttr(RES_CHRATR_CROSSEDOUT))
.GetStrikeout() != STRIKEOUT_NONE;
}
sal_Bool SwFltShell::GetContour()
{
return ((SvxContourItem&)GetNodeOrStyAttr(RES_CHRATR_CONTOUR)).GetValue();
}
sal_Bool SwFltShell::GetCaseKapitaelchen()
{
return ((SvxCaseMapItem&)GetNodeOrStyAttr(RES_CHRATR_CASEMAP))
.GetCaseMap() == SVX_CASEMAP_KAPITAELCHEN;
}
sal_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(sal_uInt16 nWhich)
{
ASSERT(sal_False, "GetCellAttr ausserhalb von normalem Text");
return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
}
sal_Bool SwFltOutBase::BeginTable()
{
ASSERT(sal_False, "BeginTable ausserhalb von normalem Text");
return sal_False;
}
void SwFltOutBase::NextTableCell()
{
ASSERT(sal_False, "NextTableCell ausserhalb von normalem Text");
}
void SwFltOutBase::NextTableRow()
{
ASSERT(sal_False, "NextTableRow ausserhalb von normalem Text");
}
void SwFltOutBase::SetTableWidth(SwTwips /*nW*/)
{
ASSERT(sal_False, "SetTableWidth ausserhalb von normalem Text");
}
void SwFltOutBase::SetTableOrient(sal_Int16 /*eOri*/)
{
ASSERT(sal_False, "SetTableOrient ausserhalb von normalem Text");
}
void SwFltOutBase::SetCellWidth(SwTwips /*nWidth*/, sal_uInt16 /*nCell*/)
{
ASSERT(sal_False, "SetCellWidth ausserhalb von normalem Text");
}
void SwFltOutBase::SetCellHeight(SwTwips /*nH*/)
{
ASSERT(sal_False, "SetCellHeight ausserhalb von normalem Text");
}
void SwFltOutBase::SetCellBorder(const SvxBoxItem& /*rFmtBox*/, sal_uInt16 /*nCell*/)
{
ASSERT(sal_False, "SetCellBorder ausserhalb von normalem Text");
}
void SwFltOutBase::SetCellSpace(sal_uInt16 /*nSp*/)
{
ASSERT(sal_False, "SetCellSpace ausserhalb von normalem Text");
}
void SwFltOutBase::DeleteCell(sal_uInt16 /*nCell*/)
{
ASSERT(sal_False, "DeleteCell ausserhalb von normalem Text");
}
void SwFltOutBase::EndTable()
{
ASSERT(sal_False, "EndTable ausserhalb von normalem Text");
}
/*virtual*/ sal_Bool SwFltOutDoc::IsInTable()
{
return pTable != 0;
};
sal_Bool SwFltOutDoc::BeginTable()
{
if(bReadNoTbl)
return sal_False;
if (pTable){
ASSERT(sal_False, "BeginTable in Table");
return sal_False;
}
// Alle Attribute schliessen, da sonst Attribute
// entstehen koennen, die in Flys reinragen
rStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
rEndStack.SetAttr( *pPaM->GetPoint(), 0, sal_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, sal_False, sal_False ); // TODO MULTIHEADER
nTableWidth = 0;
((SwTable*)pTable)->LockModify(); // Nichts automatisch anpassen!
// set pam in 1. table cell
usTableX =
usTableY = 0;
SeekCell(usTableY, usTableX, sal_True);
return sal_True;
}
SwTableBox* SwFltOutDoc::GetBox(sal_uInt16 ny, sal_uInt16 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(sal_False, "SwFltOutDoc:GetBox:pTableLines");
return 0;
}
if( ny >= pTableLines->Count() ){ // Notbremse
ASSERT( sal_False, "SwFltOutDoc:GetBox:ny >= Count()");
ny = pTableLines->Count() - 1;
}
SwTableLine* pTableLine = (*pTableLines)[ny];
if(!pTableLine){
ASSERT(sal_False, "SwFltOutDoc:GetBox:pTableLine");
return 0;
}
SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes();
if(!pTableBoxes){
ASSERT(sal_False, "SwFltOutDoc:GetBox:pTableBoxes");
return 0;
}
if( nx >= pTableBoxes->Count() ){ // Notbremse
ASSERT(sal_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, sal_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, sal_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, sal_uInt16 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(sal_uInt16 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,
sal_uInt16 nCell /* = USHRT_MAX */ )
{
SwTableBox* pTableBox = GetBox(usTableY, nCell);
if(pTableBox)
pTableBox->GetFrmFmt()->SetFmtAttr(rFmtBox);
}
// nicht aktiviert !!!
void SwFltOutDoc::SetCellSpace(sal_uInt16 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(sal_uInt16 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, sal_False );
rEndStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
if (GetDoc().GetCurrentViewShell()){ //swmod 071108//swmod 071225
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;
}
sal_Bool SwFltOutDoc::SeekCell(short nRow, short nCol, sal_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 ((sal_uInt16)nRow >= pTableLines->Count())
{
ASSERT((sal_uInt16)nRow >= pTableLines->Count(), "SwFltOutDoc");
return sal_False;
}
pTableLine = (*pTableLines)[nRow];
pTableBoxes = &pTableLine->GetTabBoxes();
if (nCol >= pTableBoxes->Count())
return sal_False;
pTableBox = (*pTableBoxes)[nCol];
if( !pTableBox->GetSttNd() )
{
ASSERT(pTableBox->GetSttNd(), "SwFltOutDoc");
return sal_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 sal_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;
}
sal_Bool SwFltOutBase::BeginFly( RndStdIds eAnchor /*= FLY_AT_PARA*/,
sal_Bool bAbsolutePos /*= sal_False*/,
const SfxItemSet*
#ifdef DBG_UTIL
pMoreAttrs /*= 0*/
#endif
)
{
ASSERT(!pMoreAttrs, "SwFltOutBase:BeginFly mit pMoreAttrs" );
eFlyAnchor = eAnchor;
bFlyAbsPos = bAbsolutePos; // Bloedsinn eigentlich
return sal_True;
}
/*virtual*/ void SwFltOutBase::SetFlyAnchor( RndStdIds eAnchor )
{
if( !IsInFly() ){
ASSERT( sal_False, "SetFlyAnchor() ohne Fly" );
return;
}
if ( eAnchor == FLY_AS_CHAR ){
ASSERT( sal_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 */ sal_Bool SwFltOutDoc::IsInFly()
{
return pFly != 0;
};
SwFrmFmt* SwFltOutDoc::MakeFly( RndStdIds eAnchor, SfxItemSet* pSet )
{
pFly = (SwFlyFrmFmt*)GetDoc().MakeFlySection( eAnchor, pPaM->GetPoint(),
pSet );
return pFly;
}
sal_Bool SwFltOutDoc::BeginFly( RndStdIds eAnchor /*= FLY_AT_PARA*/,
sal_Bool bAbsolutePos /*= sal_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, sal_False );
rEndStack.SetAttr( *pPaM->GetPoint(), 0, sal_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 sal_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(sal_uInt16 nWhich)
{
if (pFly){
return pFly->GetFmtAttr( nWhich );
}else{
ASSERT(pFly, "GetFlyAttr ohne Fly");
return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
}
}
void SwFltOutDoc::EndFly()
{
if( pTable ){
ASSERT( sal_False, "SwFltOutDoc::EndFly() in Table" );
return;
}
// Alle Attribute schliessen, da sonst Attribute
// entstehen koennen, die aus Flys rausragen
rStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
rEndStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
*pPaM->GetPoint() = *pFlySavedPos; // restore Cursor
delete pFlySavedPos;
pFlySavedPos = 0;
SwFltOutBase::EndFly();
pFly = 0;
}
//-----------------------------------------------------------------------------
// Flys in SwFltFormatCollection
//-----------------------------------------------------------------------------
/*virtual*/ sal_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(sal_uInt16 nWhich)
{
// ASSERT( pFlyAttrs, "GetFlyFrmAttr ohne Coll-FlyAttrs" );
if( pFlyAttrs )
return pFlyAttrs->Get( nWhich, sal_False );
else
return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
}
sal_Bool SwFltFormatCollection::BeginFly( RndStdIds eAnchor /*= FLY_AT_PARA*/,
sal_Bool bAbsolutePos /*= sal_False*/,
const SfxItemSet* pMoreAttrs /*= 0*/ )
{
SwFltOutBase::BeginFly( eAnchor, bAbsolutePos, pMoreAttrs );
bHasFly = sal_True;
return sal_True;
}
void SwFltFormatCollection::EndFly() // Wird nie aufgerufen
{
}
sal_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 sal_False;
}
//-----------------------------------------------------------------------------
// Flys in SwFltShell
//-----------------------------------------------------------------------------
sal_Bool SwFltShell::BeginFly( RndStdIds eAnchor /*= FLY_AT_PARA*/,
sal_Bool bAbsolutePos /*= sal_False*/ )
{
if (pOut->IsInFly()){
ASSERT(sal_False, "BeginFly in Fly");
return sal_False;
}
if (pOutDoc->IsInTable()){
ASSERT(sal_False, "BeginFly in Table");
return sal_False;
}
pOut->BeginFly( eAnchor, bAbsolutePos, pColls[nAktStyle]->GetpFlyAttrs() );
eSubMode = Fly;
return sal_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(sal_False, "EndFly ohne Fly");
return;
}
if (pOutDoc->IsInTable()){ // Table verschraenkt mit Fly macht keinen Sinn
ASSERT(sal_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(sal_False, "Fussnote in Fly nicht erlaubt");
return;
}
if( pOutDoc->IsInTable() ){
ASSERT(sal_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, sal_False );
// aEndStack.SetAttr( *pPaM->GetPoint(), 0, sal_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, sal_False );
// aEndStack.SetAttr( *pPaM->GetPoint(), 0, sal_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(sal_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(sal_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;
sal_Bool bFollow = (pFirstPageDesc != 0);
SwPageDesc* pNewPD;
sal_uInt16 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(), sal_False, bFollow ),
pFirstPageDesc, sal_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( sal_False )
{
Reset(); // Default-Attrs loeschen und Auto-Flag
}
SwFltFormatCollection::SwFltFormatCollection(
SwDoc& _rDoc, const String& rName ) :
SwFltOutBase(_rDoc),
pFlyAttrs( 0 ),
bHasFly( sal_False )
{
pColl = _rDoc.MakeTxtFmtColl(rName, (SwTxtFmtColl*)_rDoc.GetDfltTxtFmtColl());
Reset(); // Default-Attrs loeschen und Auto-Flag
}
void SwFltShell::NextStyle(sal_uInt16 nWhich, sal_uInt16 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: */