bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / filter / ww1 / fltshell.cxx
blob634d4bc9ff2181e999dcd38efd827e6ce4888c94
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <ctype.h>
22 #include <hintids.hxx>
23 #include <hints.hxx>
24 #include <vcl/graphicfilter.hxx>
26 #include <vcl/graph.hxx>
27 #include <svl/urihelper.hxx>
28 #include <editeng/boxitem.hxx>
29 #include <editeng/wghtitem.hxx>
30 #include <editeng/cmapitem.hxx>
31 #include <editeng/contouritem.hxx>
32 #include <editeng/postitem.hxx>
33 #include <editeng/crossedoutitem.hxx>
34 #include <svl/stritem.hxx>
35 #include <unotools/charclass.hxx>
36 #include <txtftn.hxx>
37 #include <fmtpdsc.hxx>
38 #include <fmtftn.hxx>
39 #include <fmtanchr.hxx>
40 #include <fmtrfmrk.hxx>
41 #include <fmtclds.hxx>
42 #include <fmtfld.hxx>
43 #include <fmtfsize.hxx>
44 #include <fmthdft.hxx>
45 #include <fmtcntnt.hxx>
46 #include <redline.hxx>
47 #include <pam.hxx>
48 #include <doc.hxx>
49 #include <ndtxt.hxx>
50 #include <frmatr.hxx>
51 #include <fldbas.hxx> // RES_SETEXPFLD
52 #include <charatr.hxx> // class SwFmtRefMark
53 #include <swtable.hxx> // class SwTableLines, ...
54 #include <tox.hxx>
55 #include <expfld.hxx> // SwExpField
56 #include <section.hxx> // class SwSection
57 #include <tblsel.hxx> // class SwSelBoxes
58 #include <pagedesc.hxx>
59 #include <docsh.hxx> // class SwDocSh
60 #include <fltshell.hxx>
61 #include <viewsh.hxx>
62 #include <shellres.hxx>
65 using namespace com::sun::star;
67 static SwCntntNode* GetCntntNode(SwDoc* pDoc, SwNodeIndex& rIdx, bool bNext)
69 SwCntntNode * pCNd = rIdx.GetNode().GetCntntNode();
70 if(!pCNd && 0 == (pCNd = bNext ? pDoc->GetNodes().GoNext(&rIdx)
71 : pDoc->GetNodes().GoPrevious(&rIdx)))
73 pCNd = bNext ? pDoc->GetNodes().GoPrevious(&rIdx)
74 : pDoc->GetNodes().GoNext(&rIdx);
75 OSL_ENSURE(pCNd, "kein ContentNode gefunden");
77 return pCNd;
80 // ------ Stack-Eintrag fuer die gesamten - Attribute vom Text -----------
81 SwFltStackEntry::SwFltStackEntry(const SwPosition& rStartPos, SfxPoolItem* pHt)
82 : m_aMkPos(rStartPos)
83 , m_aPtPos(rStartPos)
84 , mnStartCP(-1)
85 , mnEndCP(-1)
86 , bIsParaEnd(false)
88 pAttr = pHt; // speicher eine Kopie vom Attribut
89 bOld = sal_False; // used for marking Attributes *before* skipping field results
90 bOpen = sal_True; // locke das Attribut --> darf erst
91 bConsumedByField = sal_False;
94 SwFltStackEntry::~SwFltStackEntry()
96 // Attribut kam zwar als Pointer, wird aber hier geloescht
97 delete pAttr;
100 void SwFltStackEntry::SetEndPos(const SwPosition& rEndPos)
102 // Attribut freigeben und das Ende merken.
103 // Alles mit sal_uInt16's, weil sonst beim Einfuegen von neuem Text an der
104 // Cursor-Position auch der Bereich vom Attribut weiter
105 // verschoben wird.
106 // Das ist aber nicht das gewollte!
107 bOpen = sal_False; // freigeben und das ENDE merken
108 m_aPtPos.SetPos(rEndPos);
112 bool SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, bool bCheck,
113 const SwFltPosition &rMkPos, const SwFltPosition &rPtPos, bool bIsParaEnd,
114 sal_uInt16 nWhich)
116 // does this range actually contain something?
117 // empty range is allowed if at start of empty paragraph
118 // fields are special: never have range, so leave them
120 // The only position of 0x0D will not be able to make region in the old logic
121 // because it is beyond the length of para...need special consideration here.
122 SwCntntNode *const pCntntNode(
123 SwNodeIndex(rMkPos.m_nNode, +1).GetNode().GetCntntNode());
124 if (rMkPos == rPtPos &&
125 ((0 != rPtPos.m_nCntnt) || (pCntntNode && (0 != pCntntNode->Len())))
126 && (RES_TXTATR_FIELD != nWhich)
127 && !(bIsParaEnd && pCntntNode && pCntntNode->IsTxtNode() && 0 != pCntntNode->Len() ))
129 return false;
131 // !!! Die Content-Indizies beziehen sich immer auf den Node !!!
132 rRegion.GetPoint()->nNode = rMkPos.m_nNode.GetIndex() + 1;
133 SwCntntNode* pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, true);
134 rRegion.GetPoint()->nContent.Assign(pCNd, rMkPos.m_nCntnt);
135 rRegion.SetMark();
136 if (rMkPos.m_nNode != rPtPos.m_nNode)
138 rRegion.GetPoint()->nNode = rPtPos.m_nNode.GetIndex() + 1;
139 pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, false);
141 rRegion.GetPoint()->nContent.Assign(pCNd, rPtPos.m_nCntnt);
142 OSL_ENSURE( CheckNodesRange( rRegion.Start()->nNode,
143 rRegion.End()->nNode, sal_True ),
144 "atttribute or similar crosses section-boundaries" );
145 if( bCheck )
146 return CheckNodesRange( rRegion.Start()->nNode,
147 rRegion.End()->nNode, sal_True );
148 else
149 return true;
152 bool SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, bool bCheck) const
154 return MakeRegion(pDoc, rRegion, bCheck, m_aMkPos, m_aPtPos, bIsParaEnd,
155 pAttr->Which());
158 SwFltControlStack::SwFltControlStack(SwDoc* pDo, sal_uLong nFieldFl)
159 : nFieldFlags(nFieldFl),bHasSdOD(true), bSdODChecked(false), pDoc(pDo), bIsEndStack(false)
164 SwFltControlStack::~SwFltControlStack()
166 OSL_ENSURE(maEntries.empty(), "There are still Attributes on the stack");
169 // MoveAttrs() ist fuer folgendes Problem:
170 // Wenn ueber den Stack ein Feld wie z.B. "Variable setzen" gesetzt wird,
171 // verschiebt sich der Text um ein \xff - Zeichen, und alle folgenden
172 // Attribute stimmen in ihrer Position nicht mehr.
173 // Dann muss MoveAttrs() nach dem Setzen des Attributes ins Doc gerufen werden,
174 // so dass alle Attribut-Positionen,
175 // die im selben Absatz weiter hinten stehen, um 1 Zeichen weiter
176 // nach rechts verschoben werden.
177 void SwFltControlStack::MoveAttrs( const SwPosition& rPos )
179 size_t nCnt = maEntries.size();
180 sal_uLong nPosNd = rPos.nNode.GetIndex();
181 sal_uInt16 nPosCt = rPos.nContent.GetIndex() - 1;
183 for (size_t i=0; i < nCnt; ++i)
185 SwFltStackEntry& rEntry = maEntries[i];
186 if (
187 (rEntry.m_aMkPos.m_nNode.GetIndex()+1 == nPosNd) &&
188 (rEntry.m_aMkPos.m_nCntnt >= nPosCt)
191 rEntry.m_aMkPos.m_nCntnt++;
192 OSL_ENSURE( rEntry.m_aMkPos.m_nCntnt
193 <= pDoc->GetNodes()[nPosNd]->GetCntntNode()->Len(),
194 "Attribut-Anfang hinter Zeilenende" );
196 if (
197 (rEntry.m_aPtPos.m_nNode.GetIndex()+1 == nPosNd) &&
198 (rEntry.m_aPtPos.m_nCntnt >= nPosCt)
201 rEntry.m_aPtPos.m_nCntnt++;
202 OSL_ENSURE( rEntry.m_aPtPos.m_nCntnt
203 <= pDoc->GetNodes()[nPosNd]->GetCntntNode()->Len(),
204 "Attribut-Ende hinter Zeilenende" );
209 void SwFltControlStack::MarkAllAttrsOld()
211 size_t nCnt = maEntries.size();
212 for (sal_uInt16 i=0; i < nCnt; ++i)
213 maEntries[i].bOld = sal_True;
216 namespace
218 bool couldExtendEntry(const SwFltStackEntry *pExtendCandidate,
219 const SfxPoolItem& rAttr)
221 return (pExtendCandidate &&
222 !pExtendCandidate->bConsumedByField &&
223 //potentially more, but lets keep it simple
224 (isPARATR_LIST(rAttr.Which()) || (isCHRATR(rAttr.Which()) && rAttr.Which() != RES_CHRATR_FONT && rAttr.Which() != RES_CHRATR_FONTSIZE)) &&
225 *(pExtendCandidate->pAttr) == rAttr);
229 void SwFltControlStack::NewAttr(const SwPosition& rPos, const SfxPoolItem& rAttr)
231 sal_uInt16 nWhich = rAttr.Which();
232 // Ende von evtl. gleichen Attributen auf dem Stack Setzen, damit sich die
233 // Attribute nicht auf dem Stack haeufen
234 SwFltStackEntry *pExtendCandidate = SetAttr(rPos, nWhich);
235 if (couldExtendEntry(pExtendCandidate, rAttr))
237 //Here we optimize by seeing if there is an attribute uncommited
238 //to the document which
240 //a) has the same value as this attribute
241 //b) is already open, or ends at the same place as where we're starting
242 //from. If so we merge it with this one and elide adding another
243 //to the stack
244 pExtendCandidate->SetEndPos(rPos);
245 pExtendCandidate->bOpen=true;
247 else
249 SwFltStackEntry *pTmp = new SwFltStackEntry(rPos, rAttr.Clone() );
250 pTmp->SetStartCP(GetCurrAttrCP());
251 maEntries.push_back(pTmp);
255 void SwFltControlStack::DeleteAndDestroy(Entries::size_type nCnt)
257 OSL_ENSURE(nCnt < maEntries.size(), "Out of range!");
258 if (nCnt < maEntries.size())
260 myEIter aElement = maEntries.begin() + nCnt;
261 maEntries.erase(aElement);
263 //Clear the para end position recorded in reader intermittently for the least impact on loading performance
264 //Because the attributes handled based on the unit of para
265 if ( empty() )
267 ClearParaEndPosition();
268 bHasSdOD = true;
269 bSdODChecked = false;
273 // SwFltControlStack::StealAttr() loescht Attribute des angegebenen Typs vom Stack.
274 // Als nAttrId sind erlaubt: 0 fuer alle, oder ein spezieller Typ.
275 // Damit erscheinen sie nicht in der Doc-Struktur. Dabei werden nur die
276 // Attribute entfernt, die im selben Absatz wie rPos stehen.
277 // Wird fuer Grafik-Apos -> Grafiken benutzt.
278 void SwFltControlStack::StealAttr(const SwNodeIndex& rNode, sal_uInt16 nAttrId)
280 size_t nCnt = maEntries.size();
282 while (nCnt)
284 nCnt --;
285 SwFltStackEntry& rEntry = maEntries[nCnt];
286 if (rEntry.m_aPtPos.m_nNode.GetIndex()+1 == rNode.GetIndex() &&
287 (!nAttrId || nAttrId == rEntry.pAttr->Which()))
289 DeleteAndDestroy(nCnt); // loesche aus dem Stack
294 // SwFltControlStack::KillUnlockedAttr() loescht alle Attribute vom Stack,
295 // welche punktuell auf rPos aufgespannt sind.
296 // Damit erscheinen sie nicht in der Doc-Struktur.
297 // Wird im WW Import benoetigt zum ignorieren der auf dem 0x0c Section-
298 // Break-Symbol gesetzten Attribute.
299 void SwFltControlStack::KillUnlockedAttrs(const SwPosition& rPos)
301 SwFltPosition aFltPos(rPos);
303 size_t nCnt = maEntries.size();
304 while( nCnt )
306 nCnt --;
307 SwFltStackEntry& rEntry = maEntries[nCnt];
308 if( !rEntry.bOld
309 && !rEntry.bOpen
310 && (rEntry.m_aMkPos == aFltPos)
311 && (rEntry.m_aPtPos == aFltPos))
313 DeleteAndDestroy( nCnt ); // loesche aus dem Stack
318 // Alle gelockten Attribute freigeben (unlocken) und das Ende setzen,
319 // alle anderen im Document setzen und wieder aus dem Stack loeschen
320 // Returned, ob das gesuchte Attribut / die gesuchten Attribute
321 // ueberhaupt auf dem Stack standen
322 SwFltStackEntry* SwFltControlStack::SetAttr(const SwPosition& rPos,
323 sal_uInt16 nAttrId, sal_Bool bTstEnde, long nHand,
324 sal_Bool consumedByField)
326 SwFltStackEntry *pRet = NULL;
328 SwFltPosition aFltPos(rPos);
330 OSL_ENSURE(!nAttrId ||
331 (POOLATTR_BEGIN <= nAttrId && POOLATTR_END > nAttrId) ||
332 (RES_FLTRATTR_BEGIN <= nAttrId && RES_FLTRATTR_END > nAttrId),
333 "Falsche Id fuers Attribut");
335 myEIter aI = maEntries.begin();
336 while (aI != maEntries.end())
338 bool bLastEntry = aI == maEntries.end() - 1;
340 SwFltStackEntry& rEntry = *aI;
341 if (rEntry.bOpen)
343 // setze das Ende vom Attribut
344 bool bF = false;
345 if (!nAttrId )
347 bF = true;
349 else if (nAttrId == rEntry.pAttr->Which())
351 if( nAttrId != RES_FLTR_BOOKMARK )
353 // Handle abfragen
354 bF = true;
356 else if (nHand == ((SwFltBookmark*)(rEntry.pAttr))->GetHandle())
358 bF = true;
361 if (bF)
363 rEntry.bConsumedByField = consumedByField;
364 rEntry.SetEndPos(rPos);
365 rEntry.SetEndCP(GetCurrAttrCP());
366 if (bLastEntry && nAttrId == rEntry.pAttr->Which())
368 //potential candidate for merging with an identical
369 //property beginning at rPos
370 pRet = &rEntry;
373 ++aI;
374 continue;
377 // ist die Endposition die Cursor-Position, dann noch nicht
378 // ins Dokument setzen, es muss noch Text folgen;
379 // ausser am Dokumentende. (Attribut-Expandierung !!)
380 // Beim Ende-Stack niemals ausser am DocEnde reinsetzen
381 if (bTstEnde)
383 if (bIsEndStack)
385 ++aI;
386 continue;
389 //defer inserting this attribute into the document until
390 //we advance to the next node, or finish processing the document
391 if (rEntry.m_aPtPos.m_nNode.GetIndex() == aFltPos.m_nNode.GetIndex())
393 if (bLastEntry && nAttrId == rEntry.pAttr->Which() &&
394 rEntry.m_aPtPos.m_nCntnt == aFltPos.m_nCntnt)
396 //potential candidate for merging with an identical
397 //property beginning at rPos
398 pRet = &rEntry;
401 ++aI;
402 continue;
405 SetAttrInDoc(rPos, rEntry);
406 aI = maEntries.erase(aI);
409 return pRet;
412 static void MakePoint(const SwFltStackEntry& rEntry, SwDoc* pDoc,
413 SwPaM& rRegion)
415 // der Anker ist der Point vom Pam. Dieser wird beim Einfugen von Text usw.
416 // veraendert; darum wird er auf dem Stack gespeichert. Das Attribut muss
417 // nur noch im Format gesetzt werden.
418 rRegion.DeleteMark();
419 rRegion.GetPoint()->nNode = rEntry.m_aMkPos.m_nNode.GetIndex() + 1;
420 SwCntntNode* pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, true);
421 rRegion.GetPoint()->nContent.Assign(pCNd, rEntry.m_aMkPos.m_nCntnt);
424 // MakeBookRegionOrPoint() ist wie MakeRegionOrPoint, aber die besonderen
425 // Beschraenkungen von Bookmarks in Tabellen werden beachtet.
426 // ( Anfang und Ende muessen in selber Zelle sein )
427 static void MakeBookRegionOrPoint(const SwFltStackEntry& rEntry, SwDoc* pDoc,
428 SwPaM& rRegion, sal_Bool bCheck )
430 if (rEntry.MakeRegion(pDoc, rRegion, bCheck )){
431 // sal_Bool b1 = rNds[rRegion.GetPoint()->nNode]->FindTableNode() != 0;
432 if (rRegion.GetPoint()->nNode.GetNode().FindTableBoxStartNode()
433 != rRegion.GetMark()->nNode.GetNode().FindTableBoxStartNode())
435 rRegion.Exchange(); // Ungueltiger Bereich
436 rRegion.DeleteMark(); // -> beide auf Mark
438 }else{
439 MakePoint(rEntry, pDoc, rRegion);
443 // IterateNumrulePiece() sucht von rTmpStart bis rEnd den ersten
444 // fuer Numrules gueltigen Bereich heraus.
446 // rNds sind die Doc-Nodes
447 // rEnd ist Bereichs-Ende,
448 // rTmpStart ist ReinRaus-Parameter: Anfang des zu untersuchenden Bereiches rein,
449 // Anfang des gueltigen Bereichs raus
450 // rTmpEnd ist raus-Parameter
451 // Return-Bool ist true fuer gueltigen Bereich
452 static bool IterateNumrulePiece( const SwNodeIndex& rEnd,
453 SwNodeIndex& rTmpStart, SwNodeIndex& rTmpEnd )
455 while( ( rTmpStart <= rEnd )
456 && !( rTmpStart.GetNode().IsTxtNode() ) ) // suche gueltigen Anfang
457 ++rTmpStart;
459 rTmpEnd = rTmpStart;
460 while( ( rTmpEnd <= rEnd )
461 && ( rTmpEnd.GetNode().IsTxtNode() ) ) // suche gueltiges Ende + 1
462 ++rTmpEnd;
464 rTmpEnd--; // gueltiges Ende
466 return rTmpStart <= rTmpEnd; // gueltig ?
469 //***This function will check whether there is existing individual attribute positon for 0x0D***/
470 //The check will happen only once for a paragraph during loading
471 bool SwFltControlStack::HasSdOD()
473 bool bRet = false;
475 for (Entries::iterator it = maEntries.begin(); it != maEntries.end(); ++it)
477 SwFltStackEntry& rEntry = *it;
478 if ( rEntry.mnStartCP == rEntry.mnEndCP )
480 if ( CheckSdOD(rEntry.mnStartCP,rEntry.mnEndCP) )
482 bRet = true;
483 break;
488 return bRet;
491 void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
492 SwFltStackEntry& rEntry)
494 SwPaM aRegion( rTmpPos );
496 switch(rEntry.pAttr->Which())
498 case RES_FLTR_ANCHOR:
500 SwFrmFmt* pFmt = ((SwFltAnchor*)rEntry.pAttr)->GetFrmFmt();
501 if (pFmt != NULL)
503 MakePoint(rEntry, pDoc, aRegion);
504 SwFmtAnchor aAnchor(pFmt->GetAnchor());
505 aAnchor.SetAnchor(aRegion.GetPoint());
506 pFmt->SetFmtAttr(aAnchor);
507 // Damit die Frames bei Einfuegen in existierendes Doc
508 // erzeugt werden (erst nach Setzen des Ankers!):
509 if(pDoc->GetCurrentViewShell() //swmod 071108//swmod 071225
510 && (FLY_AT_PARA == pFmt->GetAnchor().GetAnchorId()))
512 pFmt->MakeFrms();
516 break;
517 case RES_FLTR_STYLESHEET:
518 break;
519 case RES_TXTATR_FIELD:
520 break;
521 case RES_TXTATR_TOXMARK:
522 break;
523 case RES_FLTR_NUMRULE: // Numrule 'reinsetzen
525 const String& rNumNm = ((SfxStringItem*)rEntry.pAttr)->GetValue();
526 SwNumRule* pRul = pDoc->FindNumRulePtr( rNumNm );
527 if( pRul )
529 if( rEntry.MakeRegion(pDoc, aRegion, sal_True))
531 SwNodeIndex aTmpStart( aRegion.Start()->nNode );
532 SwNodeIndex aTmpEnd( aTmpStart );
533 SwNodeIndex& rRegEndNd = aRegion.End()->nNode;
534 while( IterateNumrulePiece( rRegEndNd,
535 aTmpStart, aTmpEnd ) )
537 SwPaM aTmpPam( aTmpStart, aTmpEnd );
538 // no start of a new list
539 pDoc->SetNumRule( aTmpPam, *pRul, false );
541 aTmpStart = aTmpEnd; // Start fuer naechstes Teilstueck
542 ++aTmpStart;
545 else
546 pDoc->DelNumRule( rNumNm );
549 break;
550 case RES_FLTR_NUMRULE_NUM:
551 break;
552 case RES_FLTR_BOOKMARK: // eigentlich nur fuer den Ende-Stack
554 SwFltBookmark* pB = (SwFltBookmark*)rEntry.pAttr;
555 const String& rName = ((SwFltBookmark*)rEntry.pAttr)->GetName();
557 if (IsFlagSet(BOOK_TO_VAR_REF))
559 if (pB->IsPgRef() && !pB->IsRef())
561 // XRefs und Bookmarks sind bereits geUpcased
562 MakeBookRegionOrPoint(rEntry, pDoc, aRegion, sal_True);
563 pDoc->InsertPoolItem(aRegion, SwFmtRefMark(rName), 0);
565 else if( !pB->IsOnlyRef() )
567 SwFieldType* pFT = pDoc->GetFldType(RES_SETEXPFLD, rName, false);
568 if (!pFT)
569 { // FieldType anlegen
570 SwSetExpFieldType aS(pDoc, rName, nsSwGetSetExpType::GSE_STRING);
571 pFT = pDoc->InsertFldType(aS);
573 SwSetExpField aFld((SwSetExpFieldType*)pFT,
574 pB->GetValSys());
575 aFld.SetSubType( nsSwExtendedSubType::SUB_INVISIBLE );
576 MakePoint(rEntry, pDoc, aRegion);
577 pDoc->InsertPoolItem(aRegion, SwFmtFld(aFld), 0);
578 MoveAttrs( *(aRegion.GetPoint()) );
581 if( !pB->IsOnlyRef() &&
582 ( !IsFlagSet(HYPO) || IsFlagSet(BOOK_AND_REF) ) && !rEntry.bConsumedByField)
584 MakeBookRegionOrPoint(rEntry, pDoc, aRegion, sal_True);
585 pDoc->getIDocumentMarkAccess()->makeMark( aRegion, rName, IDocumentMarkAccess::BOOKMARK);
588 break;
589 case RES_FLTR_TOX:
591 MakePoint(rEntry, pDoc, aRegion);
593 SwPosition* pPoint = aRegion.GetPoint();
595 SwFltTOX* pTOXAttr = (SwFltTOX*)rEntry.pAttr;
597 // test if on this node there had been a pagebreak BEFORE the
598 // tox attribut was put on the stack
599 SfxItemSet aBkSet( pDoc->GetAttrPool(), RES_PAGEDESC, RES_BREAK );
600 SwCntntNode* pNd = 0;
601 if( !pTOXAttr->HadBreakItem() || !pTOXAttr->HadPageDescItem() )
603 pNd = pPoint->nNode.GetNode().GetCntntNode();
604 if( pNd )
606 const SfxItemSet* pSet = pNd->GetpSwAttrSet();
607 const SfxPoolItem* pItem;
608 if( pSet )
610 if( !pTOXAttr->HadBreakItem()
611 && SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, sal_False, &pItem ) )
613 aBkSet.Put( *pItem );
614 pNd->ResetAttr( RES_BREAK );
616 if( !pTOXAttr->HadPageDescItem()
617 && SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, sal_False, &pItem ) )
619 aBkSet.Put( *pItem );
620 pNd->ResetAttr( RES_PAGEDESC );
626 delete pTOXAttr->GetBase();
628 // set (aboved saved and removed) the break item at the node following the TOX
629 if( aBkSet.Count() )
630 pNd->SetAttr( aBkSet );
632 break;
633 case RES_FLTR_SECTION:
634 MakePoint(rEntry, pDoc, aRegion); // bislang immer Point==Mark
635 pDoc->InsertSwSection(aRegion,
636 *(static_cast<SwFltSection*>(rEntry.pAttr))->GetSectionData(),
637 0, 0, false);
638 delete (((SwFltSection*)rEntry.pAttr)->GetSectionData());
639 break;
640 case RES_FLTR_REDLINE:
642 if (rEntry.MakeRegion(pDoc, aRegion, sal_True))
644 pDoc->SetRedlineMode((RedlineMode_t)( nsRedlineMode_t::REDLINE_ON
645 | nsRedlineMode_t::REDLINE_SHOW_INSERT
646 | nsRedlineMode_t::REDLINE_SHOW_DELETE ));
647 SwFltRedline& rFltRedline = *((SwFltRedline*)rEntry.pAttr);
649 if( USHRT_MAX != rFltRedline.nAutorNoPrev )
651 SwRedlineData aData(rFltRedline.eTypePrev,
652 rFltRedline.nAutorNoPrev,
653 rFltRedline.aStampPrev,
654 aEmptyStr,
657 pDoc->AppendRedline(new SwRedline(aData, aRegion), true);
659 SwRedlineData aData(rFltRedline.eType,
660 rFltRedline.nAutorNo,
661 rFltRedline.aStamp,
662 aEmptyStr,
665 pDoc->AppendRedline( new SwRedline(aData, aRegion), true );
666 pDoc->SetRedlineMode((RedlineMode_t)( nsRedlineMode_t::REDLINE_NONE
667 | nsRedlineMode_t::REDLINE_SHOW_INSERT
668 | nsRedlineMode_t::REDLINE_SHOW_DELETE ));
671 break;
672 default:
674 //Revised for more complex situations should be considered
675 if ( !bSdODChecked )
677 bHasSdOD = HasSdOD();
678 bSdODChecked = true;
680 sal_Int32 nStart = rEntry.GetStartCP();
681 sal_Int32 nEnd = rEntry.GetEndCP();
682 if (nStart != -1 && nEnd != -1 && nEnd >= nStart )
684 rEntry.SetIsParaEnd( IsParaEndInCPs(nStart,nEnd,bHasSdOD) );
686 if (rEntry.MakeRegion(pDoc, aRegion, sal_False))
688 nStart = rEntry.GetStartCP();
689 nEnd = rEntry.GetEndCP();
690 if (rEntry.IsParaEnd())
692 pDoc->InsertPoolItem(aRegion, *rEntry.pAttr, 0, true);
694 else
696 pDoc->InsertPoolItem(aRegion, *rEntry.pAttr, 0);
700 break;
704 bool SwFltControlStack::IsParaEndInCPs(sal_Int32 /*nStart*/, sal_Int32 /*nEnd*/,bool /*bSdOD*/) const
706 return false;
709 bool SwFltControlStack::CheckSdOD(sal_Int32 /*nStart*/, sal_Int32 /*nEnd*/)
711 return false;
714 SfxPoolItem* SwFltControlStack::GetFmtStackAttr(sal_uInt16 nWhich, sal_uInt16 * pPos)
716 size_t nSize = maEntries.size();
718 while (nSize)
720 // ist es das gesuchte Attribut ? (gueltig sind nur gelockte,
721 // also akt. gesetzte Attribute!!)
722 SwFltStackEntry &rEntry = maEntries[--nSize];
723 if (rEntry.bOpen && rEntry.pAttr->Which() == nWhich)
725 if (pPos)
726 *pPos = nSize;
727 return (SfxPoolItem*)rEntry.pAttr; // Ok, dann Ende
730 return 0;
733 const SfxPoolItem* SwFltControlStack::GetFmtAttr(const SwPosition& rPos, sal_uInt16 nWhich)
735 SfxPoolItem* pHt = GetFmtStackAttr(nWhich);
736 if (pHt)
737 return (const SfxPoolItem*)pHt;
739 // im Stack ist das Attribut nicht vorhanden, also befrage das Dokument
740 SwCntntNode * pNd = rPos.nNode.GetNode().GetCntntNode();
742 if (!pNd) // kein ContentNode, dann das dflt. Attribut
743 return &pDoc->GetAttrPool().GetDefaultItem(nWhich);
744 return &pNd->GetAttr(nWhich);
747 void SwFltControlStack::Delete(const SwPaM &rPam)
749 const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
751 if( !rPam.HasMark() || *pStt >= *pEnd )
752 return;
754 SwNodeIndex aStartNode(pStt->nNode, -1);
755 sal_uInt16 nStartIdx = pStt->nContent.GetIndex();
756 SwNodeIndex aEndNode(pEnd->nNode, -1);
757 sal_uInt16 nEndIdx = pEnd->nContent.GetIndex();
759 //We don't support deleting content that is over one node, or removing a node.
760 OSL_ENSURE(aEndNode == aStartNode, "nodes must be the same, or this method extended");
761 if (aEndNode != aStartNode)
762 return;
764 for (size_t nSize = maEntries.size(); nSize > 0;)
766 SwFltStackEntry& rEntry = maEntries[--nSize];
768 bool bEntryStartAfterSelStart =
769 (rEntry.m_aMkPos.m_nNode == aStartNode &&
770 rEntry.m_aMkPos.m_nCntnt >= nStartIdx);
772 bool bEntryStartBeforeSelEnd =
773 (rEntry.m_aMkPos.m_nNode == aEndNode &&
774 rEntry.m_aMkPos.m_nCntnt <= nEndIdx);
776 bool bEntryEndAfterSelStart = false;
777 bool bEntryEndBeforeSelEnd = false;
778 if (!rEntry.bOpen)
780 bEntryEndAfterSelStart =
781 (rEntry.m_aPtPos.m_nNode == aStartNode &&
782 rEntry.m_aPtPos.m_nCntnt >= nStartIdx);
784 bEntryEndBeforeSelEnd =
785 (rEntry.m_aPtPos.m_nNode == aEndNode &&
786 rEntry.m_aPtPos.m_nCntnt <= nEndIdx);
789 bool bTotallyContained = false;
790 if (
791 bEntryStartAfterSelStart && bEntryStartBeforeSelEnd &&
792 bEntryEndAfterSelStart && bEntryEndBeforeSelEnd
795 bTotallyContained = true;
798 if (bTotallyContained)
800 //after start, before end, delete
801 DeleteAndDestroy(nSize);
802 continue;
805 xub_StrLen nCntntDiff = nEndIdx - nStartIdx;
807 //to be adjusted
808 if (bEntryStartAfterSelStart)
810 if (bEntryStartBeforeSelEnd)
812 //move start to new start
813 rEntry.m_aMkPos.SetPos(aStartNode, nStartIdx);
815 else
816 rEntry.m_aMkPos.m_nCntnt -= nCntntDiff;
819 if (bEntryEndAfterSelStart)
821 if (bEntryEndBeforeSelEnd)
822 rEntry.m_aPtPos.SetPos(aStartNode, nStartIdx);
823 else
824 rEntry.m_aPtPos.m_nCntnt -= nCntntDiff;
827 //That's what Open is, end equal to start, and nPtCntnt is invalid
828 if (rEntry.bOpen)
829 rEntry.m_aPtPos = rEntry.m_aMkPos;
833 //------ hier stehen die Methoden von SwFltAnchor -----------
834 SwFltAnchor::SwFltAnchor(SwFrmFmt* pFmt) :
835 SfxPoolItem(RES_FLTR_ANCHOR), pFrmFmt(pFmt)
837 pClient = new SwFltAnchorClient(this);
838 pFrmFmt->Add(pClient);
841 SwFltAnchor::SwFltAnchor(const SwFltAnchor& rCpy) :
842 SfxPoolItem(RES_FLTR_ANCHOR), pFrmFmt(rCpy.pFrmFmt)
844 pClient = new SwFltAnchorClient(this);
845 pFrmFmt->Add(pClient);
848 SwFltAnchor::~SwFltAnchor()
850 delete pClient;
853 void SwFltAnchor::SetFrmFmt(SwFrmFmt * _pFrmFmt)
855 pFrmFmt = _pFrmFmt;
858 const SwFrmFmt * SwFltAnchor::GetFrmFmt() const
860 return pFrmFmt;
863 SwFrmFmt * SwFltAnchor::GetFrmFmt()
865 return pFrmFmt;
868 int SwFltAnchor::operator==(const SfxPoolItem& rItem) const
870 return pFrmFmt == ((SwFltAnchor&)rItem).pFrmFmt;
873 SfxPoolItem* SwFltAnchor::Clone(SfxItemPool*) const
875 return new SwFltAnchor(*this);
878 // SwFltAnchorClient
880 SwFltAnchorClient::SwFltAnchorClient(SwFltAnchor * pFltAnchor)
881 : m_pFltAnchor(pFltAnchor)
885 void SwFltAnchorClient::Modify(const SfxPoolItem *, const SfxPoolItem * pNew)
887 if (pNew->Which() == RES_FMT_CHG)
889 const SwFmtChg * pFmtChg = dynamic_cast<const SwFmtChg *> (pNew);
891 if (pFmtChg != NULL)
893 SwFrmFmt * pFrmFmt = dynamic_cast<SwFrmFmt *> (pFmtChg->pChangedFmt);
895 if (pFrmFmt != NULL)
896 m_pFltAnchor->SetFrmFmt(pFrmFmt);
901 //------ hier stehen die Methoden von SwFltRedline -----------
902 int SwFltRedline::operator==(const SfxPoolItem& rItem) const
904 return this == &rItem;
907 SfxPoolItem* SwFltRedline::Clone( SfxItemPool* ) const
909 return new SwFltRedline(*this);
912 //------ hier stehen die Methoden von SwFltBookmark -----------
913 SwFltBookmark::SwFltBookmark( const String& rNa, const String& rVa,
914 long nHand, sal_Bool bOnlyR )
915 : SfxPoolItem(RES_FLTR_BOOKMARK), nHandle(nHand), aName(rNa), aVal(rVa),
916 bOnlyRef(bOnlyR), bRef(sal_False), bPgRef(sal_False)
918 // eSrc: CHARSET_DONTKNOW fuer keine UEbersetzung bei operator <<
919 // Upcase wird immer gemacht.
920 // bei XXXStack.NewAttr(...) wird nie eine UEbersetzung vorgenommen.
921 // ansonsten: uebergebener Src-Charset fuer aName
922 // im Filter eingestellter Src-Charset fuer aVal ( Text )
925 SwFltBookmark::SwFltBookmark(const SwFltBookmark& rCpy)
926 : SfxPoolItem(RES_FLTR_BOOKMARK),
927 nHandle(rCpy.nHandle),
928 aName(rCpy.aName),
929 aVal(rCpy.aVal),
930 bOnlyRef(rCpy.bOnlyRef),
931 bRef(rCpy.bRef),
932 bPgRef(rCpy.bPgRef)
936 int SwFltBookmark::operator==(const SfxPoolItem& rItem) const
938 return (aName == ((SwFltBookmark&)rItem).aName)
939 && (nHandle == ((SwFltBookmark&)rItem).nHandle);
942 SfxPoolItem* SwFltBookmark::Clone(SfxItemPool*) const
944 return new SwFltBookmark(*this);
947 //------ hier stehen die Methoden von SwFltTOX -----------
949 SwFltTOX::SwFltTOX(SwTOXBase* pBase, sal_uInt16 _nCols)
950 : SfxPoolItem(RES_FLTR_TOX), pTOXBase(pBase), nCols( _nCols ),
951 bHadBreakItem( sal_False ), bHadPageDescItem( sal_False )
955 SwFltTOX::SwFltTOX(const SwFltTOX& rCpy)
956 : SfxPoolItem(RES_FLTR_TOX), pTOXBase(rCpy.pTOXBase), nCols( rCpy.nCols ),
957 bHadBreakItem( rCpy.bHadBreakItem ), bHadPageDescItem( rCpy.bHadPageDescItem )
961 int SwFltTOX::operator==(const SfxPoolItem& rItem) const
963 return pTOXBase == ((SwFltTOX&)rItem).pTOXBase;
966 SfxPoolItem* SwFltTOX::Clone(SfxItemPool*) const
968 return new SwFltTOX(*this);
971 //------ hier stehen die Methoden von SwFltSwSection -----------
973 SwFltSection::SwFltSection(SwSectionData *const pSect)
974 : SfxPoolItem(RES_FLTR_SECTION)
975 , m_pSection(pSect)
979 SwFltSection::SwFltSection(const SwFltSection& rCpy)
980 : SfxPoolItem(RES_FLTR_SECTION)
981 , m_pSection(rCpy.m_pSection)
985 int SwFltSection::operator==(const SfxPoolItem& rItem) const
987 return m_pSection == ((SwFltSection&)rItem).m_pSection;
990 SfxPoolItem* SwFltSection::Clone(SfxItemPool*) const
992 return new SwFltSection(*this);
995 ///////////////////////////////////////////////////////////////////////
997 // hier beginnt der von mdt erzeugte code. dieser ist eine shell auf
998 // der writer-seite nach moeglichkeit bald fuer alle filter. die ganze
999 // schwierigkeit, texte & formatattribute einzufuegen, die positionen
1000 // zu verwalten, styles & kopf/fuszzeilen etc.
1003 //////////////////////////////////////////////////////////// SwFltShell
1004 SwFltShell::SwFltShell(SwDoc* pDoc, SwPaM& rPaM, const String& rBaseURL, sal_Bool bNew, sal_uLong nFieldFl) :
1005 pCurrentPageDesc(0),
1006 pSavedPos(0),
1007 eSubMode(None),
1008 nAktStyle(0),
1009 aStack(pDoc, nFieldFl),
1010 aEndStack(pDoc, nFieldFl),
1011 pPaM(new SwPaM(*(rPaM.GetPoint()))),
1012 sBaseURL(rBaseURL),
1013 nPageDescOffset(GetDoc().GetPageDescCnt()),
1014 eSrcCharSet(RTL_TEXTENCODING_MS_1252),
1015 bNewDoc(bNew),
1016 bStdPD(sal_False),
1017 bProtect(sal_False)
1019 memset( pColls, 0, sizeof( pColls ) );
1020 pOutDoc = new SwFltOutDoc( *pDoc, pPaM, aStack, aEndStack );
1021 pOut = pOutDoc;
1023 if( !bNewDoc ){ // in ein Dokument einfuegen ?
1024 // Da immer ganze Zeile eingelesen werden, muessen
1025 // evtl. Zeilen eingefuegt / aufgebrochen werden
1026 const SwPosition* pPos = pPaM->GetPoint();
1027 const SwTxtNode* pSttNd = pPos->nNode.GetNode().GetTxtNode();
1028 sal_uInt16 nCntPos = pPos->nContent.GetIndex();
1029 if (nCntPos && !pSttNd->GetTxt().isEmpty())
1030 // EinfuegePos nicht in leerer Zeile
1031 pDoc->SplitNode( *pPos, false ); // neue Zeile erzeugen
1032 if (!pSttNd->GetTxt().isEmpty())
1033 { // InsertPos not on empty line
1034 pDoc->SplitNode( *pPos, false ); // neue Zeile
1035 pPaM->Move( fnMoveBackward ); // gehe in leere Zeile
1038 // verhinder das Einlesen von Tabellen in Fussnoten / Tabellen
1039 sal_uLong nNd = pPos->nNode.GetIndex();
1040 bool bReadNoTbl = 0 != pSttNd->FindTableNode() ||
1041 ( nNd < pDoc->GetNodes().GetEndOfInserts().GetIndex() &&
1042 pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() < nNd );
1043 if( bReadNoTbl )
1044 pOutDoc->SetReadNoTable();
1046 pCurrentPageDesc = &pDoc->GetPageDesc( 0 ); // Standard
1050 SwFltShell::~SwFltShell()
1052 sal_uInt16 i;
1054 if (eSubMode == Style)
1055 EndStyle();
1056 if( pOutDoc->IsInTable() ) // falls nicht ordentlich abgeschlossen
1057 EndTable();
1058 if( pOutDoc->IsInFly() )
1059 EndFly();
1061 GetDoc().SetUpdateExpFldStat(true);
1062 GetDoc().SetInitDBFields(sal_True);
1063 aStack.SetAttr(*pPaM->GetPoint(), 0, sal_False);
1064 aStack.SetAttr(*pPaM->GetPoint(), 0, sal_False);
1065 aEndStack.SetAttr(*pPaM->GetPoint(), 0, sal_False);
1066 aEndStack.SetAttr(*pPaM->GetPoint(), 0, sal_False);
1067 if( bProtect ){ // Das ganze Doc soll geschuetzt sein
1069 SwDoc& rDoc = GetDoc();
1070 // 1. SectionFmt und Section anlegen
1071 SwSectionFmt* pSFmt = rDoc.MakeSectionFmt( 0 );
1072 SwSectionData aSectionData(CONTENT_SECTION, OUString("PMW-Protect"));
1073 aSectionData.SetProtectFlag( true );
1074 // 2. Start- und EndIdx suchen
1075 const SwNode* pEndNd = &rDoc.GetNodes().GetEndOfContent();
1076 SwNodeIndex aEndIdx( *pEndNd, -1L );
1077 const SwStartNode* pSttNd = pEndNd->StartOfSectionNode();
1078 SwNodeIndex aSttIdx( *pSttNd, 1L ); // +1 -> hinter StartNode
1079 // Section einfuegen
1080 // Section einfuegen
1081 rDoc.GetNodes().InsertTextSection(
1082 aSttIdx, *pSFmt, aSectionData, 0, &aEndIdx, false );
1084 if( !IsFlagSet(SwFltControlStack::DONT_HARD_PROTECT) ){
1085 SwDocShell* pDocSh = rDoc.GetDocShell();
1086 if( pDocSh )
1087 pDocSh->SetReadOnlyUI( sal_True );
1090 // Pagedescriptoren am Dokument updaten (nur so werden auch die
1091 // linken Seiten usw. eingestellt).
1093 GetDoc().ChgPageDesc( 0, GetDoc().GetPageDesc( 0 )); // PageDesc "Standard"
1094 for (i=nPageDescOffset;i<GetDoc().GetPageDescCnt();i++)
1096 const SwPageDesc& rPD = GetDoc().GetPageDesc(i);
1097 GetDoc().ChgPageDesc(i, rPD);
1100 delete pPaM;
1101 for (i=0; i<sizeof(pColls)/sizeof(*pColls); i++)
1102 delete pColls[i];
1103 delete pOutDoc;
1106 SwFltShell& SwFltShell::operator << ( const String& rStr )
1108 OSL_ENSURE(eSubMode != Style, "char insert while in style-mode");
1109 GetDoc().InsertString( *pPaM, rStr );
1110 return *this;
1113 void SwFltShell::ConvertUStr( String& rInOut )
1115 rInOut = GetAppCharClass().uppercase( rInOut );
1118 // QuoteString() wandelt CRs abhaengig von nFieldIniFlags in '\n' oder "\0x0d"
1119 OUString SwFltShell::QuoteStr( const OUString& rIn )
1121 OUStringBuffer sOut( rIn );
1122 sal_Bool bAllowCr = aStack.IsFlagSet( SwFltControlStack::ALLOW_FLD_CR );
1124 for( sal_Int32 n = 0; n < sOut.getLength(); ++n )
1126 switch( sOut[ n ] )
1128 case 0x0a:
1129 sOut.remove( n, 1 ); // 0xd 0xa wird zu \n
1130 break;
1132 case 0x0b:
1133 case 0x0c:
1134 case 0x0d:
1135 if( bAllowCr )
1136 sOut[n] = '\n';
1137 break;
1140 return sOut.makeStringAndClear();
1143 SwFltShell& SwFltShell::operator << ( const sal_Unicode c )
1145 OSL_ENSURE( eSubMode != Style, "char insert while in style-mode");
1146 GetDoc().InsertString( *pPaM, OUString(c) );
1147 return *this;
1150 SwFltShell& SwFltShell::AddError( const sal_Char* pErr )
1152 String aName(OUString("ErrorTag"));
1153 SwFieldType* pFT = GetDoc().GetFldType( RES_SETEXPFLD, aName, false );
1154 if( pFT == 0)
1156 SwSetExpFieldType aS(&GetDoc(), aName, nsSwGetSetExpType::GSE_STRING);
1157 pFT = GetDoc().InsertFldType(aS);
1159 SwSetExpField aFld( (SwSetExpFieldType*)pFT,
1160 OUString::createFromAscii( pErr ));
1161 //, VVF_INVISIBLE
1162 GetDoc().InsertPoolItem(*pPaM, SwFmtFld(aFld), 0);
1163 return *this;
1166 SwFltShell& SwFltShell::operator << (Graphic& rGraphic)
1168 // embedded Grafik !!
1169 GetDoc().Insert(*pPaM, aEmptyStr, aEmptyStr, &rGraphic, NULL, NULL, NULL);
1170 return *this;
1173 void SwFltShell::NextParagraph()
1175 GetDoc().AppendTxtNode(*pPaM->GetPoint());
1178 void SwFltShell::NextPage()
1180 NextParagraph();
1181 GetDoc().InsertPoolItem(*pPaM,
1182 SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK), 0);
1185 SwFltShell& SwFltShell::AddGraphic( const String& rPicName )
1187 // embedded:
1188 GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
1189 Graphic aGraphic;
1190 // one of: GFF_NOT GFF_BMP GFF_GIF GFF_JPG GFF_PCD GFF_PCX GFF_PNG
1191 // GFF_TIF GFF_XBM GFF_DXF GFF_MET GFF_PCT GFF_SGF GFF_SVM GFF_WMF
1192 // GFF_SGV GFF_XXX
1193 INetURLObject aDir(
1194 URIHelper::SmartRel2Abs(
1195 INetURLObject(GetBaseURL()), rPicName,
1196 URIHelper::GetMaybeFileHdl()) );
1197 switch (rFilter.ImportGraphic(aGraphic, aDir))
1199 case GRFILTER_OK:
1200 *this << aGraphic;
1201 break;
1202 case GRFILTER_OPENERROR:
1203 case GRFILTER_IOERROR:
1204 case GRFILTER_FORMATERROR:
1205 case GRFILTER_VERSIONERROR:
1206 case GRFILTER_FILTERERROR:
1207 case GRFILTER_ABORT:
1208 case GRFILTER_TOOBIG:
1209 default:
1210 AddError( "picture import error" );
1211 break;
1213 return *this;
1216 SwFltShell& SwFltShell::SetStyle( sal_uInt16 nStyle )
1218 SwFltFormatCollection* p = pColls[ nStyle ];
1220 if (p)
1222 if( !pOutDoc->IsInTable() && nStyle != nAktStyle )
1224 if( pColls[nAktStyle]->IsInFly() && pOutDoc->IsInFly() )
1225 pOutDoc->EndFly();
1226 if( p->IsInFly() )
1227 p->BeginStyleFly( pOutDoc );
1229 GetDoc().SetTxtFmtColl(*pPaM, p->GetColl());
1230 nAktStyle = nStyle;
1232 else
1234 OSL_FAIL( "Ungueltiger SwFltStyleCode" );
1236 return *this;
1239 SwFltShell& SwFltShell::operator << (SwFltBookmark& aBook)
1241 ConvertUStr( aBook.aName );
1242 aBook.aVal = QuoteStr(aBook.aVal);
1243 aEndStack.NewAttr(*pPaM->GetPoint(), aBook);
1244 return *this;
1247 void SwFltShell::SetBookEnd(long nHandle)
1249 aEndStack.SetAttr( *pPaM->GetPoint(), RES_FLTR_BOOKMARK, sal_True, nHandle );
1252 SwFltShell& SwFltShell::EndItem( sal_uInt16 nAttrId )
1254 switch( nAttrId )
1256 case RES_FLTR_BOOKMARK:
1257 OSL_FAIL( "Falscher Aufruf fuer Bookmark-Ende" );
1258 break;
1260 case RES_FLTR_TOX:
1261 aEndStack.SetAttr(*pPaM->GetPoint(), nAttrId);
1262 break;
1264 default:
1265 aStack.SetAttr(*pPaM->GetPoint(), nAttrId);
1266 break;
1268 return *this;
1271 SwFltShell& SwFltShell::operator << (const SwField& rField)
1273 GetDoc().InsertPoolItem(*pPaM, SwFmtFld(rField), 0);
1274 return *this;
1277 /*virtual*/ SwFltOutBase& SwFltOutDoc::operator << (const SfxPoolItem& rItem)
1279 rStack.NewAttr(*pPaM->GetPoint(), rItem);
1280 return *this;
1283 /*virtual*/ SwFltOutBase& SwFltFormatCollection::operator <<
1284 (const SfxPoolItem& rItem)
1286 pColl->SetFmtAttr(rItem);
1287 return *this;
1290 const SfxPoolItem& SwFltOutDoc::GetAttr(sal_uInt16 nWhich)
1292 return *rStack.GetFmtAttr(*pPaM->GetPoint(), nWhich);
1295 const SfxPoolItem& SwFltFormatCollection::GetAttr(sal_uInt16 nWhich)
1297 return GetColl()->GetFmtAttr(nWhich); // mit Parents
1300 // GetNodeOrStyAttr holt Attribute fuer Toggle- und Modify-Attribute:
1301 // Bei Formatdefinitionen aus dem altuellen Style mit Parents
1302 // sonst aus dem Node mit Parents
1303 // Im Stack wird nicht nachgesehen
1305 const SfxPoolItem& SwFltOutDoc::GetNodeOrStyAttr(sal_uInt16 nWhich)
1307 SwCntntNode * pNd = pPaM->GetPoint()->nNode.GetNode().GetCntntNode();
1308 if (pNd) // ContentNode: Attribut mit Parent
1309 return pNd->GetAttr(nWhich);
1310 else // kein ContentNode, dann das dflt. Attribut
1311 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1314 const SfxPoolItem& SwFltFormatCollection::GetNodeOrStyAttr(sal_uInt16 nWhich)
1316 return GetColl()->GetFmtAttr(nWhich); // mit Parents
1319 const SfxPoolItem& SwFltShell::GetNodeOrStyAttr(sal_uInt16 nWhich)
1321 return pOut->GetNodeOrStyAttr( nWhich );
1324 const SfxPoolItem& SwFltShell::GetAttr(sal_uInt16 nWhich)
1326 return pOut->GetAttr( nWhich );
1329 const SfxPoolItem& SwFltShell::GetFlyFrmAttr(sal_uInt16 nWhich)
1331 return pOut->GetFlyFrmAttr( nWhich );
1334 SwFieldType* SwFltShell::GetSysFldType(sal_uInt16 eWhich)
1336 return GetDoc().GetSysFldType(eWhich);
1339 bool SwFltShell::GetWeightBold()
1341 return ((SvxWeightItem&)GetNodeOrStyAttr(RES_CHRATR_WEIGHT)).GetWeight()
1342 != WEIGHT_NORMAL;
1345 bool SwFltShell::GetPostureItalic()
1347 return ((SvxPostureItem&)GetNodeOrStyAttr(RES_CHRATR_POSTURE)).GetPosture()
1348 != ITALIC_NONE;
1351 bool SwFltShell::GetCrossedOut()
1353 return ((SvxCrossedOutItem&)GetNodeOrStyAttr(RES_CHRATR_CROSSEDOUT))
1354 .GetStrikeout() != STRIKEOUT_NONE;
1357 bool SwFltShell::GetContour()
1359 return ((SvxContourItem&)GetNodeOrStyAttr(RES_CHRATR_CONTOUR)).GetValue();
1362 bool SwFltShell::GetCaseKapitaelchen()
1364 return ((SvxCaseMapItem&)GetNodeOrStyAttr(RES_CHRATR_CASEMAP))
1365 .GetCaseMap() == SVX_CASEMAP_KAPITAELCHEN;
1368 bool SwFltShell::GetCaseVersalien()
1370 return ((SvxCaseMapItem&)GetNodeOrStyAttr(RES_CHRATR_CASEMAP))
1371 .GetCaseMap() == SVX_CASEMAP_VERSALIEN;
1374 //-------------------------------------------------------------------------
1375 // Tabellen
1376 //-------------------------------------------------------------------------
1378 SwFltOutBase::~SwFltOutBase()
1382 SwFltOutBase::SwFltOutBase(SwDoc& rDocu)
1383 : rDoc(rDocu), eFlyAnchor(FLY_AT_PARA), bFlyAbsPos(false)
1387 const SfxPoolItem& SwFltOutBase::GetCellAttr(sal_uInt16 nWhich)
1389 OSL_FAIL("GetCellAttr ausserhalb von normalem Text");
1390 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1393 bool SwFltOutBase::BeginTable()
1395 OSL_FAIL("BeginTable ausserhalb von normalem Text");
1396 return false;
1399 void SwFltOutBase::NextTableCell()
1401 OSL_FAIL("NextTableCell ausserhalb von normalem Text");
1404 void SwFltOutBase::NextTableRow()
1406 OSL_FAIL("NextTableRow ausserhalb von normalem Text");
1409 void SwFltOutBase::SetTableWidth(SwTwips /*nW*/)
1411 OSL_FAIL("SetTableWidth ausserhalb von normalem Text");
1414 void SwFltOutBase::SetTableOrient(sal_Int16 /*eOri*/)
1416 OSL_FAIL("SetTableOrient ausserhalb von normalem Text");
1419 void SwFltOutBase::SetCellWidth(SwTwips /*nWidth*/, sal_uInt16 /*nCell*/)
1421 OSL_FAIL("SetCellWidth ausserhalb von normalem Text");
1424 void SwFltOutBase::SetCellHeight(SwTwips /*nH*/)
1426 OSL_FAIL("SetCellHeight ausserhalb von normalem Text");
1429 void SwFltOutBase::SetCellBorder(const SvxBoxItem& /*rFmtBox*/, sal_uInt16 /*nCell*/)
1431 OSL_FAIL("SetCellBorder ausserhalb von normalem Text");
1434 void SwFltOutBase::SetCellSpace(sal_uInt16 /*nSp*/)
1436 OSL_FAIL("SetCellSpace ausserhalb von normalem Text");
1439 void SwFltOutBase::DeleteCell(sal_uInt16 /*nCell*/)
1441 OSL_FAIL("DeleteCell ausserhalb von normalem Text");
1444 void SwFltOutBase::EndTable()
1446 OSL_FAIL("EndTable ausserhalb von normalem Text");
1449 /*virtual*/ sal_Bool SwFltOutDoc::IsInTable()
1451 return pTable != 0;
1454 bool SwFltOutDoc::BeginTable()
1456 if(bReadNoTbl)
1457 return false;
1459 if (pTable){
1460 OSL_FAIL("BeginTable in Table");
1461 return false;
1463 // Alle Attribute schliessen, da sonst Attribute
1464 // entstehen koennen, die in Flys reinragen
1465 rStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
1466 rEndStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
1468 // create table:
1469 OSL_ENSURE(pTabSavedPos == NULL, "SwFltOutDoc");
1470 pTabSavedPos = new SwPosition(*pPaM->GetPoint());
1471 pTable = GetDoc().InsertTable(
1472 SwInsertTableOptions( tabopts::HEADLINE_NO_BORDER, 1 ),
1473 *pTabSavedPos, 1, 1, text::HoriOrientation::LEFT, 0, 0, sal_False, sal_False ); // TODO MULTIHEADER
1474 nTableWidth = 0;
1475 ((SwTable*)pTable)->LockModify(); // Nichts automatisch anpassen!
1476 // set pam in 1. table cell
1477 usTableX =
1478 usTableY = 0;
1479 SeekCell(usTableY, usTableX, sal_True);
1480 return true;
1483 SwTableBox* SwFltOutDoc::GetBox(sal_uInt16 ny, sal_uInt16 nx /*= USHRT_MAX */)
1485 if(!pTable){
1486 OSL_ENSURE(pTable, "GetBox ohne Tabelle");
1487 return 0;
1489 if( nx == USHRT_MAX ) // aktuelle Zelle
1490 nx = usTableX;
1492 // get structs to table cells
1493 const SwTableLines* pTableLines = &pTable->GetTabLines();
1494 if(!pTableLines){
1495 OSL_FAIL("SwFltOutDoc:GetBox:pTableLines");
1496 return 0;
1498 if( ny >= pTableLines->size() ){ // Notbremse
1499 OSL_FAIL( "SwFltOutDoc:GetBox:ny >= Count()");
1500 ny = pTableLines->size() - 1;
1502 SwTableLine* pTableLine = (*pTableLines)[ny];
1503 if(!pTableLine){
1504 OSL_FAIL("SwFltOutDoc:GetBox:pTableLine");
1505 return 0;
1507 SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes();
1508 if(!pTableBoxes){
1509 OSL_FAIL("SwFltOutDoc:GetBox:pTableBoxes");
1510 return 0;
1512 if( nx >= pTableBoxes->size() ){ // Notbremse
1513 OSL_FAIL("SwFltOutDoc:GetBox:nx >= Count()");
1514 nx = pTableBoxes->size() - 1;
1516 SwTableBox* pTableBox = (*pTableBoxes)[nx];
1518 OSL_ENSURE(pTableBox != 0, "SwFltOutDoc:GetBox:pTableBox");
1519 return pTableBox;
1522 void SwFltOutDoc::NextTableCell()
1524 if(!pTable){
1525 OSL_ENSURE(pTable, "NextTableCell ohne Tabelle");
1526 return;
1528 const SwTableLines* pTableLines = &pTable->GetTabLines();
1529 SwTableLine* pTableLine = (*pTableLines)[usTableY];
1530 SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes();
1531 SwTableBox* pTableBox = (*pTableBoxes)[usTableX];
1532 OSL_ENSURE(pTableBox != 0, "SwFltOutDoc:NextTableCell:pTableBox");
1533 if(!pTableBox)
1534 return;
1535 //#pragma message(__FILE__ "(?) : Sw's const problem")
1536 // insert cells:
1537 if (++usTableX >= pTableBoxes->size())
1538 GetDoc().GetNodes().InsBoxen(
1539 GetDoc().IsIdxInTbl(pPaM->GetPoint()->nNode),
1540 pTableLine,
1541 (SwTableBoxFmt*)pTableBox->GetFrmFmt(),
1542 GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ),
1544 pTableBoxes->size());
1545 SeekCell(usTableY, usTableX, sal_True);
1546 pTableBox = (*pTableBoxes)[usTableX];
1547 OSL_ENSURE(pTableBox != 0, "SwFltOutDoc:pTableBox");
1548 if(pTableBox)
1549 (*pTableBoxes)[usTableX]->ClaimFrmFmt();
1552 void SwFltOutDoc::NextTableRow()
1554 SwTableBox* pTableBox = GetBox(usTableY, 0);
1555 if (pTableBox)
1557 // duplicate row:
1558 SwSelBoxes aSelBoxes;
1559 aSelBoxes.insert( pTableBox );
1560 GetDoc().InsertRow(aSelBoxes);
1561 usTableX = 0;
1562 SeekCell(++usTableY, usTableX, sal_True);
1563 GetDoc().SetTxtFmtColl(*pPaM,
1564 GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ));
1568 void SwFltOutDoc::SetTableWidth(SwTwips nSwWidth)
1570 if(!pTable){
1571 OSL_ENSURE(pTable, "SetTableWidth ohne Tabelle");
1572 return;
1574 OSL_ENSURE( nSwWidth > MINLAY, "Tabellenbreite <= MINLAY" );
1575 if( nSwWidth != nTableWidth ){
1576 if( nTableWidth ) // Nicht beim ersten Setzen
1577 SplitTable();
1578 pTable->GetFrmFmt()->SetFmtAttr( SwFmtFrmSize(ATT_VAR_SIZE, nSwWidth));
1579 nTableWidth = nSwWidth;
1583 void SwFltOutDoc::SetTableOrient(sal_Int16 eOri)
1585 if(!pTable){
1586 OSL_ENSURE(pTable, "SetTableOrient ohne Tabelle");
1587 return;
1589 pTable->GetFrmFmt()->SetFmtAttr( SwFmtHoriOrient( 0, eOri ));
1592 void SwFltOutDoc::SetCellWidth(SwTwips nWidth, sal_uInt16 nCell /* = USHRT_MAX */ )
1594 if(!pTable){
1595 OSL_ENSURE(pTable, "SetCellWidth ohne Tabelle");
1596 return;
1598 OSL_ENSURE( nWidth > MINLAY, "Tabellenzellenbreite <= MINLAY" );
1599 if (nWidth < MINLAY)
1600 nWidth = MINLAY;
1602 SwTableBox* pTableBox = GetBox(usTableY, nCell);
1603 if(pTableBox && pTableBox->GetFrmFmt() ){
1604 SwFmtFrmSize aFmtFrmSize(ATT_FIX_SIZE);
1605 aFmtFrmSize.SetWidth(nWidth);
1606 pTableBox->GetFrmFmt()->SetFmtAttr(aFmtFrmSize);
1610 void SwFltOutDoc::SetCellHeight(SwTwips nHeight)
1612 if(!pTable){
1613 OSL_ENSURE(pTable, "SetCellHeight ohne Tabelle");
1614 return;
1617 const SwTableLines* pTableLines = &pTable->GetTabLines();
1618 SwTableLine* pTableLine = (*pTableLines)[usTableY];
1619 SwFmtFrmSize aFmtFrmSize(ATT_MIN_SIZE, 0, 0);
1620 if (nHeight < MINLAY)
1621 nHeight = MINLAY;
1622 aFmtFrmSize.SetHeight(nHeight);
1623 pTableLine->GetFrmFmt()->SetFmtAttr(aFmtFrmSize);
1626 const SfxPoolItem& SwFltOutDoc::GetCellAttr(sal_uInt16 nWhich)
1628 if (!pTable){
1629 OSL_ENSURE(pTable, "GetCellAttr ohne Table");
1630 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1633 SwTableBox* pTableBox = GetBox(usTableY, usTableX);
1634 if(!pTableBox)
1635 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1636 return pTableBox->GetFrmFmt()->GetFmtAttr( nWhich );
1639 void SwFltOutDoc::SetCellBorder(const SvxBoxItem& rFmtBox,
1640 sal_uInt16 nCell /* = USHRT_MAX */ )
1642 SwTableBox* pTableBox = GetBox(usTableY, nCell);
1643 if(pTableBox)
1644 pTableBox->GetFrmFmt()->SetFmtAttr(rFmtBox);
1647 // nicht aktiviert !!!
1648 void SwFltOutDoc::SetCellSpace(sal_uInt16 nDist)
1650 if(!pTable){
1651 OSL_ENSURE(pTable, "SetCellSpace ohne Tabelle");
1652 return;
1654 SwTableBox* pTableBox = GetBox(usTableY, usTableX);
1655 if(!pTableBox)
1656 return;
1658 SvxBoxItem aFmtBox( *((SvxBoxItem*)
1659 &pTableBox->GetFrmFmt()->GetFmtAttr( RES_BOX )));
1661 // versteh ich nich, sven: if (!nDist) nDist = 18; // ca. 0.03 cm
1662 if (nDist > 42) // max. 0.7 mm
1663 nDist = 42;
1664 else
1665 if (nDist < MIN_BORDER_DIST)
1666 nDist = MIN_BORDER_DIST;
1667 aFmtBox.SetDistance(nDist);
1668 pTableBox->GetFrmFmt()->SetFmtAttr(aFmtBox);
1671 void SwFltOutDoc::DeleteCell(sal_uInt16 nCell /* = USHRT_MAX */)
1673 SwTableBox* pTableBox = GetBox(usTableY, nCell);
1674 if( pTableBox )
1676 SwSelBoxes aSelBoxes;
1677 aSelBoxes.insert( pTableBox );
1678 GetDoc().DeleteRowCol(aSelBoxes);
1679 usTableX--;
1683 void SwFltOutDoc::SplitTable()
1685 if(!pTable)
1687 OSL_ENSURE(pTable, "SplitTable ohne Tabelle");
1688 return;
1690 SwTableBox* pAktBox = GetBox(usTableY, usTableX);
1691 SwTableBox* pSplitBox = GetBox(usTableY - 1, 0);
1692 GetDoc().GetNodes().SplitTable(SwNodeIndex(*pSplitBox->GetSttNd()), false);
1693 pTable = &pAktBox->GetSttNd()->FindTableNode()->GetTable();
1694 usTableY = 0;
1697 void SwFltOutDoc::EndTable()
1699 if (!pTable){
1700 OSL_ENSURE(pTable, "EndTable ohne Table");
1701 return;
1703 // Alle Attribute schliessen, da sonst Attribute
1704 // entstehen koennen, die in Flys reinragen
1705 rStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
1706 rEndStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
1708 if (GetDoc().GetCurrentViewShell()){ //swmod 071108//swmod 071225
1709 SwTableNode* pTableNode = GetDoc().IsIdxInTbl(
1710 pPaM->GetPoint()->nNode);
1711 pTableNode->DelFrms();
1712 pTableNode->MakeFrms(&pPaM->GetPoint()->nNode);
1715 *pPaM->GetPoint() = *pTabSavedPos; // restore Cursor
1716 delete pTabSavedPos;
1717 pTabSavedPos = 0;
1718 ((SwTable*)pTable)->UnlockModify(); // Test, nuetzt nichts gegen Assert
1719 pTable = 0;
1720 nTableWidth = 0;
1723 sal_Bool SwFltOutDoc::SeekCell(short nRow, short nCol, sal_Bool bPam)
1725 // get structs to table cells
1726 const SwTableLines* pTableLines = &pTable->GetTabLines();
1727 SwTableLine* pTableLine = (*pTableLines)[usTableY];
1728 SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes();
1729 SwTableBox* pTableBox = (*pTableBoxes)[usTableX];
1731 if ((sal_uInt16)nRow >= pTableLines->size())
1733 OSL_ENSURE((sal_uInt16)nRow >= pTableLines->size(), "SwFltOutDoc");
1734 return sal_False;
1736 pTableLine = (*pTableLines)[nRow];
1737 pTableBoxes = &pTableLine->GetTabBoxes();
1738 if (nCol >= (short)pTableBoxes->size())
1739 return sal_False;
1740 pTableBox = (*pTableBoxes)[nCol];
1741 if( !pTableBox->GetSttNd() )
1743 OSL_ENSURE(pTableBox->GetSttNd(), "SwFltOutDoc");
1744 return sal_False;
1746 if(bPam)
1748 pPaM->GetPoint()->nNode = pTableBox->GetSttIdx() + 1;
1749 pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
1750 GetDoc().SetTxtFmtColl(*pPaM,
1751 GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ));
1753 return sal_True;
1757 //-----------------------------------------------------------------------------
1758 // Flys in SwFltOutBase
1759 //-----------------------------------------------------------------------------
1761 SfxItemSet* SwFltOutBase::NewFlyDefaults()
1763 // Unbedingt noetige Standardwerte setzen ( falls diese Werte nicht
1764 // spaeter explizit gesetzt werden )
1766 SfxItemSet* p = new SfxItemSet( GetDoc().GetAttrPool(),
1767 RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
1768 SwFmtFrmSize aSz( ATT_VAR_SIZE, MINFLY, MINFLY );
1769 // Default: Breite 100% ( = PMW:Auto )
1770 aSz.SetWidthPercent( 100 ); // Hoehe: Auto
1771 p->Put( aSz );
1772 p->Put( SwFmtHoriOrient( 0, text::HoriOrientation::NONE, text::RelOrientation::FRAME ));
1773 return p;
1776 bool SwFltOutBase::BeginFly( RndStdIds eAnchor /*= FLY_AT_PARA*/,
1777 sal_Bool bAbsolutePos /*= sal_False*/,
1778 const SfxItemSet* pMoreAttrs /*= 0*/)
1780 (void) pMoreAttrs; // unused in non-debug
1781 OSL_ENSURE(!pMoreAttrs, "SwFltOutBase:BeginFly mit pMoreAttrs" );
1782 eFlyAnchor = eAnchor;
1783 bFlyAbsPos = bAbsolutePos; // Bloedsinn eigentlich
1784 return true;
1787 /*virtual*/ void SwFltOutBase::SetFlyAnchor( RndStdIds eAnchor )
1789 if( !IsInFly() ){
1790 OSL_FAIL( "SetFlyAnchor() ohne Fly" );
1791 return;
1793 if ( eAnchor == FLY_AS_CHAR ){
1794 OSL_FAIL( "SetFlyAnchor( FLY_AS_CHAR ) nicht implementiert" );
1795 return;
1797 SwFmtAnchor& rAnchor = (SwFmtAnchor&)GetFlyFrmAttr( RES_ANCHOR );
1798 rAnchor.SetType( eAnchor );
1801 void SwFltOutBase::EndFly()
1803 if( bFlyAbsPos ){
1804 // hier muessen die absoluten Positionen am Fly noch in
1805 // die Writer-Koordinaten umgerechnet werden.
1809 //-----------------------------------------------------------------------------
1810 // Flys in SwFltDoc
1811 //-----------------------------------------------------------------------------
1813 /* virtual */ bool SwFltOutDoc::IsInFly()
1815 return pFly != 0;
1818 SwFrmFmt* SwFltOutDoc::MakeFly( RndStdIds eAnchor, SfxItemSet* pSet )
1820 pFly = (SwFlyFrmFmt*)GetDoc().MakeFlySection( eAnchor, pPaM->GetPoint(),
1821 pSet );
1822 return pFly;
1825 bool SwFltOutDoc::BeginFly( RndStdIds eAnchor,
1826 sal_Bool bAbsolutePos ,
1827 const SfxItemSet* pMoreAttrs)
1830 SwFltOutBase::BeginFly( eAnchor, bAbsolutePos, 0 );
1831 SfxItemSet* pSet = NewFlyDefaults();
1833 // Alle Attribute schliessen, da sonst Attribute entstehen koennen,
1834 // die in Flys reinragen
1835 rStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
1836 rEndStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
1838 // create Fly:
1839 OSL_ENSURE(pFlySavedPos == NULL, "BeginFly in Fly"); // rekursiv geht noch nicht
1840 pFlySavedPos = new SwPosition(*pPaM->GetPoint());
1843 SwFmtAnchor aAnchor( eAnchor, 1 );
1845 // Wenn Fly-Attribute im Style waren, dann jetzt als Defaults reinsetzen
1846 if (pMoreAttrs)
1847 pSet->Put(*pMoreAttrs);
1849 // dieses NICHT bei Seitengebundenem Fly mit Seiten-NUMMER !
1850 aAnchor.SetAnchor(pPaM->GetPoint()); // braucht erstaunlicherweise
1851 // den Stack nicht
1853 pSet->Put( aAnchor );
1854 SwFrmFmt* pF = MakeFly( eAnchor, pSet );
1855 delete pSet;
1857 // set pam in Fly
1858 const SwFmtCntnt& rCntnt = pF->GetCntnt();
1859 OSL_ENSURE( rCntnt.GetCntntIdx(), "Kein Inhalt vorbereitet." );
1860 pPaM->GetPoint()->nNode = rCntnt.GetCntntIdx()->GetIndex() + 1;
1861 SwCntntNode *pNode = pPaM->GetCntntNode();
1862 pPaM->GetPoint()->nContent.Assign( pNode, 0 );
1864 return true;
1867 /*virtual*/ void SwFltOutDoc::SetFlyFrmAttr(const SfxPoolItem& rAttr)
1869 if (pFly){
1870 pFly->SetFmtAttr( rAttr );
1871 }else{
1872 OSL_ENSURE(pFly, "SetFlyAttr ohne Doc-Fly");
1873 return;
1877 /*virtual*/ const SfxPoolItem& SwFltOutDoc::GetFlyFrmAttr(sal_uInt16 nWhich)
1879 if (pFly){
1880 return pFly->GetFmtAttr( nWhich );
1881 }else{
1882 OSL_ENSURE(pFly, "GetFlyAttr ohne Fly");
1883 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1887 void SwFltOutDoc::EndFly()
1889 if( pTable ){
1890 OSL_FAIL( "SwFltOutDoc::EndFly() in Table" );
1891 return;
1893 // Alle Attribute schliessen, da sonst Attribute
1894 // entstehen koennen, die aus Flys rausragen
1895 rStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
1896 rEndStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
1898 *pPaM->GetPoint() = *pFlySavedPos; // restore Cursor
1899 delete pFlySavedPos;
1900 pFlySavedPos = 0;
1901 SwFltOutBase::EndFly();
1902 pFly = 0;
1905 //-----------------------------------------------------------------------------
1906 // Flys in SwFltFormatCollection
1907 //-----------------------------------------------------------------------------
1908 /*virtual*/ bool SwFltFormatCollection::IsInFly()
1910 return bHasFly;
1913 /*virtual*/ void SwFltFormatCollection::SetFlyFrmAttr(const SfxPoolItem& rAttr)
1915 if (!pFlyAttrs)
1916 pFlyAttrs = new SfxItemSet( GetDoc().GetAttrPool(),
1917 RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
1918 pFlyAttrs->Put( rAttr );
1921 /*virtual*/ const SfxPoolItem& SwFltFormatCollection::GetFlyFrmAttr(sal_uInt16 nWhich)
1923 if( pFlyAttrs )
1924 return pFlyAttrs->Get( nWhich, sal_False );
1925 else
1926 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1929 bool SwFltFormatCollection::BeginFly( RndStdIds eAnchor,
1930 sal_Bool bAbsolutePos,
1931 const SfxItemSet* pMoreAttrs)
1934 SwFltOutBase::BeginFly( eAnchor, bAbsolutePos, pMoreAttrs );
1935 bHasFly = true;
1936 return true;
1939 void SwFltFormatCollection::EndFly() // Wird nie aufgerufen
1943 bool SwFltFormatCollection::BeginStyleFly( SwFltOutDoc* pOutDoc )
1945 OSL_ENSURE( pOutDoc, "BeginStyleFly ohne pOutDoc" );
1946 OSL_ENSURE( pOutDoc && !pOutDoc->IsInFly(), "BeginStyleFly in Fly" );
1947 if( pOutDoc && !pOutDoc->IsInFly() )
1948 return pOutDoc->BeginFly( eFlyAnchor, bFlyAbsPos, pFlyAttrs );
1949 else
1950 return false;
1953 //-----------------------------------------------------------------------------
1954 // Flys in SwFltShell
1955 //-----------------------------------------------------------------------------
1957 bool SwFltShell::BeginFly( RndStdIds eAnchor,
1958 sal_Bool bAbsolutePos)
1960 if (pOut->IsInFly()){
1961 OSL_FAIL("BeginFly in Fly");
1962 return false;
1964 if (pOutDoc->IsInTable()){
1965 OSL_FAIL("BeginFly in Table");
1966 return false;
1968 pOut->BeginFly( eAnchor, bAbsolutePos, pColls[nAktStyle]->GetpFlyAttrs() );
1969 eSubMode = Fly;
1970 return true;
1973 void SwFltShell::SetFlyXPos( short nXPos, sal_Int16 eHRel,
1974 sal_Int16 eHAlign)
1976 SetFlyFrmAttr( SwFmtHoriOrient( nXPos, eHAlign, eHRel ) );
1979 void SwFltShell::SetFlyYPos( short nYPos, sal_Int16 eVRel,
1980 sal_Int16 eVAlign)
1982 SetFlyFrmAttr( SwFmtVertOrient( nYPos, eVAlign, eVRel ) );
1986 void SwFltShell::EndFly()
1988 if (!pOut->IsInFly()){
1989 OSL_FAIL("EndFly ohne Fly");
1990 return;
1992 if (pOutDoc->IsInTable()){ // Table verschraenkt mit Fly macht keinen Sinn
1993 OSL_FAIL("EndFly in Table ( verschraenkt )");
1994 EndTable(); // -> Table beenden
1996 pOut->EndFly();
1997 eSubMode = None;
2000 //-----------------------------------------------------------------------------
2001 // Fussnoten
2002 //-----------------------------------------------------------------------------
2004 void SwFltShell::BeginFootnote()
2006 if( pOut->IsInFly() ){ // Passiert z.B. bei Fussnote in Fly
2007 OSL_FAIL("Fussnote in Fly nicht erlaubt");
2008 return;
2010 if( pOutDoc->IsInTable() ){
2011 OSL_FAIL("Fussnote in Table z.Zt. nicht erlaubt");
2012 return;
2015 // Alle Attribute schliessen, da sonst Attribute entstehen koennen,
2016 // die in Fussnoten reinragen
2017 aStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
2018 // EndStack erstmal nicht zwangs-Schliessen, damit Bookmarks ueber
2019 // Fussnoten im PMW uebernommen werden
2021 SwFmtFtn aFtn;
2022 GetDoc().InsertPoolItem(*pPaM, aFtn, 0);
2023 OSL_ENSURE(pSavedPos == NULL, "SwFltShell");
2024 pSavedPos = new SwPosition(*pPaM->GetPoint());
2025 pPaM->Move(fnMoveBackward, fnGoCntnt);
2026 SwTxtNode* pTxt = pPaM->GetNode()->GetTxtNode();
2027 SwTxtAttr *const pFN = pTxt->GetTxtAttrForCharAt(
2028 pPaM->GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN);
2029 if( !pFN ){ // Passiert z.B. bei Fussnote in Fly
2030 OSL_ENSURE(pFN, "Probleme beim Anlegen des Fussnoten-Textes");
2031 return;
2033 const SwNodeIndex* pStartIndex = ((SwTxtFtn*)pFN)->GetStartNode();
2034 OSL_ENSURE(pStartIndex, "Probleme beim Anlegen des Fussnoten-Textes");
2035 pPaM->GetPoint()->nNode = pStartIndex->GetIndex() + 1;
2036 pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
2037 eSubMode = Footnote;
2040 void SwFltShell::EndFootnote()
2042 if(!pSavedPos)
2043 return;
2044 // Alle Attribute schliessen, da sonst Attribute
2045 // entstehen koennen, die aus Fussnoten rausragen
2046 aStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
2047 // EndStack erstmal nicht zwangs-Schliessen, damit Bookmarks ueber
2048 // Fussnoten im PMW uebernommen werden
2050 *pPaM->GetPoint() = *pSavedPos; // restore Cursor
2051 delete pSavedPos;
2052 pSavedPos = 0;
2055 void SwFltShell::BeginHeader(SwPageDesc* /*pPD*/)
2057 SwFrmFmt* pFmt = &pCurrentPageDesc->GetMaster();
2058 SwFrmFmt* pHdFtFmt;
2059 pFmt->SetFmtAttr(SwFmtHeader(sal_True));
2060 pHdFtFmt = (SwFrmFmt*)pFmt->GetHeader().GetHeaderFmt();
2061 const SwNodeIndex* pStartIndex = pHdFtFmt->GetCntnt().GetCntntIdx();
2062 if (!pStartIndex)
2063 return;
2064 OSL_ENSURE(pSavedPos == NULL, "SwFltShell");
2065 pSavedPos = new SwPosition(*pPaM->GetPoint());
2066 pPaM->GetPoint()->nNode = pStartIndex->GetIndex() + 1;
2067 pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
2068 eSubMode = Header;
2071 void SwFltShell::BeginFooter(SwPageDesc* /*pPD*/)
2073 SwFrmFmt* pFmt = &pCurrentPageDesc->GetMaster();
2074 SwFrmFmt* pHdFtFmt;
2075 pFmt->SetFmtAttr(SwFmtFooter(sal_True));
2076 pHdFtFmt = (SwFrmFmt*)pFmt->GetFooter().GetFooterFmt();
2077 const SwNodeIndex* pStartIndex = pHdFtFmt->GetCntnt().GetCntntIdx();
2078 if (!pStartIndex)
2079 return;
2080 OSL_ENSURE(pSavedPos == NULL, "SwFltShell");
2081 pSavedPos = new SwPosition(*pPaM->GetPoint());
2082 pPaM->GetPoint()->nNode = pStartIndex->GetIndex() + 1;
2083 pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
2084 eSubMode = Footer;
2087 void SwFltShell::EndHeaderFooter()
2089 *pPaM->GetPoint() = *pSavedPos; // restore Cursor
2090 delete pSavedPos;
2091 pSavedPos = 0;
2094 SwPageDesc* SwFltShell::MakePageDesc(SwPageDesc* pFirstPageDesc)
2096 if(bStdPD) // keine Neuen PageDescs
2097 return pCurrentPageDesc;
2099 bool bFollow = (pFirstPageDesc != 0);
2100 SwPageDesc* pNewPD;
2101 sal_uInt16 nPos;
2102 if (bFollow && pFirstPageDesc->GetFollow() != pFirstPageDesc)
2103 return pFirstPageDesc; // Fehler: hat schon Follow
2104 // Erkennung doppelter Namen fehlt noch (Wahrscheinlichkeit
2105 // fuer dopp. Namen ist gering)
2107 nPos = GetDoc().MakePageDesc( ViewShell::GetShellRes()->GetPageDescName(
2108 GetDoc().GetPageDescCnt(), bFollow ? ShellResource::FOLLOW_PAGE : ShellResource::NORMAL_PAGE),
2109 pFirstPageDesc, false );
2111 pNewPD = &GetDoc().GetPageDesc(nPos);
2112 if (bFollow)
2113 { // Dieser ist der folgende von pPageDesc
2114 pFirstPageDesc->SetFollow(pNewPD);
2115 pNewPD->SetFollow(pNewPD);
2117 else
2119 GetDoc().InsertPoolItem( *pPaM, SwFmtPageDesc( pNewPD ), 0 );
2121 pNewPD->WriteUseOn( // alle Seiten
2122 (UseOnPage)(nsUseOnPage::PD_ALL | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE));
2123 return pNewPD;
2126 ///////////////////////////////////////////////// SwFltFormatCollection
2127 SwFltFormatCollection::SwFltFormatCollection(
2128 SwDoc& _rDoc, RES_POOL_COLLFMT_TYPE nType ) :
2129 SwFltOutBase(_rDoc),
2130 pColl(_rDoc.GetTxtCollFromPool( static_cast< sal_uInt16 >(nType), false )),
2131 pFlyAttrs( 0 ),
2132 bHasFly( false )
2134 Reset(); // Default-Attrs loeschen und Auto-Flag
2137 SwFltFormatCollection::SwFltFormatCollection(
2138 SwDoc& _rDoc, const String& rName ) :
2139 SwFltOutBase(_rDoc),
2140 pFlyAttrs( 0 ),
2141 bHasFly( false )
2143 pColl = _rDoc.MakeTxtFmtColl(rName, (SwTxtFmtColl*)_rDoc.GetDfltTxtFmtColl());
2144 Reset(); // Default-Attrs loeschen und Auto-Flag
2147 void SwFltShell::NextStyle(sal_uInt16 nWhich, sal_uInt16 nNext)
2149 OSL_ENSURE(pColls[nWhich], "Next style for noexistent style" );
2150 OSL_ENSURE(pColls[nNext], "Next style to noexistent style" );
2151 if( pColls[nWhich] && pColls[nNext] )
2152 pColls[nWhich]->GetColl()->SetNextTxtFmtColl(
2153 *pColls[nNext]->GetColl() );
2156 // UpdatePageDescs muss am Ende des Einlesevorganges aufgerufen werden, damit
2157 // der Writer den Inhalt der Pagedescs wirklich akzeptiert
2158 void UpdatePageDescs(SwDoc &rDoc, sal_uInt16 nInPageDescOffset)
2160 // Pagedescriptoren am Dokument updaten (nur so werden auch die
2161 // linken Seiten usw. eingestellt).
2163 // PageDesc "Standard"
2164 rDoc.ChgPageDesc(0, rDoc.GetPageDesc(0));
2166 // PageDescs "Konvert..."
2167 for (sal_uInt16 i = nInPageDescOffset; i < rDoc.GetPageDescCnt(); ++i)
2168 rDoc.ChgPageDesc(i, rDoc.GetPageDesc(i));
2171 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */