merge the formfield patch from ooo-build
[ooovba.git] / sw / source / filter / ww1 / fltshell.cxx
blobbf79021866100b28b129a5620e3bff633eb60c59
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fltshell.cxx,v $
10 * $Revision: 1.29 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
34 #include <ctype.h>
35 #include <hintids.hxx>
36 #include <hints.hxx>
38 #ifndef _GRAPH_HXX //autogen
39 #include <vcl/graph.hxx>
40 #endif
41 #include <svtools/urihelper.hxx>
42 #include <svx/impgrf.hxx>
43 #include <svx/boxitem.hxx>
44 #include <svx/boxitem.hxx>
45 #include <svx/wghtitem.hxx>
46 #include <svx/cmapitem.hxx>
47 #include <svx/cntritem.hxx>
48 #include <svx/postitem.hxx>
49 #include <svx/crsditem.hxx>
50 #include <svtools/stritem.hxx>
51 #include <unotools/charclass.hxx>
52 #include <txtftn.hxx>
53 #include <fmtpdsc.hxx>
54 #include <fmtftn.hxx>
55 #include <fmtanchr.hxx>
56 #include <fmtrfmrk.hxx>
57 #include <fmtclds.hxx>
58 #include <fmtfld.hxx>
59 #include <fmtfsize.hxx>
60 #include <fmthdft.hxx>
61 #include <fmtcntnt.hxx>
62 #include <redline.hxx>
63 #include <pam.hxx>
64 #include <doc.hxx>
65 #include <ndtxt.hxx>
66 #include <frmatr.hxx>
67 #include <fldbas.hxx> // RES_SETEXPFLD
68 #include <charatr.hxx> // class SwFmtRefMark
69 #include <swtable.hxx> // class SwTableLines, ...
70 #include <tox.hxx>
71 #include <expfld.hxx> // SwExpField
72 #include <section.hxx> // class SwSection
73 #include <tblsel.hxx> // class SwSelBoxes
74 #include <pagedesc.hxx>
75 #ifndef _DOCSH_HXX
76 #include <docsh.hxx> // class SwDocSh
77 #endif
78 #include <fltshell.hxx>
79 #include <viewsh.hxx>
80 #include <shellres.hxx>
82 #define MAX_FIELDLEN 64000
84 using namespace com::sun::star;
86 static SwCntntNode* GetCntntNode(SwDoc* pDoc, SwNodeIndex& rIdx, BOOL bNext)
88 SwCntntNode* pCNd = pDoc->GetNodes()[ rIdx ]->GetCntntNode();
89 if(!pCNd && 0 == (pCNd = bNext ? pDoc->GetNodes().GoNext(&rIdx)
90 : pDoc->GetNodes().GoPrevious(&rIdx)))
92 pCNd = bNext ? pDoc->GetNodes().GoPrevious(&rIdx)
93 : pDoc->GetNodes().GoNext(&rIdx);
94 ASSERT(pCNd, "kein ContentNode gefunden");
96 return pCNd;
99 // ------ Stack-Eintrag fuer die gesamten - Attribute vom Text -----------
100 SwFltStackEntry::SwFltStackEntry(const SwPosition& rStartPos, SfxPoolItem* pHt ) :
101 nMkNode(rStartPos.nNode, -1),
102 nPtNode(nMkNode)
104 // Anfang vom Bereich merken
105 nMkCntnt = rStartPos.nContent.GetIndex();
106 pAttr = pHt; // speicher eine Kopie vom Attribut
107 bOld = FALSE; // used for marking Attributes *before* skipping field results
108 bLocked = TRUE; // locke das Attribut --> darf erst
109 bCopied = FALSE; // gesetzt werden, wenn es wieder geunlocked ist
110 bConsumedByField = FALSE;
113 SwFltStackEntry::SwFltStackEntry(const SwFltStackEntry& rEntry) :
114 nMkNode(rEntry.nMkNode),
115 nPtNode(rEntry.nPtNode)
117 pAttr = rEntry.pAttr->Clone();
118 nMkCntnt= rEntry.nMkCntnt;
119 bOld = rEntry.bOld;
120 bLocked = bCopied = TRUE; // when rEntry were NOT bLocked we would never have been called
121 bConsumedByField = rEntry.bConsumedByField;
125 SwFltStackEntry::~SwFltStackEntry()
127 // Attribut kam zwar als Pointer, wird aber hier geloescht
128 if (pAttr)
129 delete pAttr;
132 void SwFltStackEntry::SetEndPos(const SwPosition& rEndPos)
134 // Attribut freigeben und das Ende merken.
135 // Alles mit USHORT's, weil sonst beim Einfuegen von neuem Text an der
136 // Cursor-Position auch der Bereich vom Attribut weiter
137 // verschoben wird.
138 // Das ist aber nicht das gewollte!
139 bLocked = FALSE; // freigeben und das ENDE merken
140 nPtNode = rEndPos.nNode.GetIndex()-1;
141 nPtCntnt = rEndPos.nContent.GetIndex();
144 BOOL SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, BOOL bCheck )
146 // wird ueberhaupt ein Bereich umspannt ??
147 // - ist kein Bereich, dann nicht returnen wenn am Anfang vom Absatz
148 // - Felder aussortieren, koennen keinen Bereich haben !!
149 if (
150 nMkNode.GetIndex() == nPtNode.GetIndex() && nMkCntnt == nPtCntnt &&
151 nPtCntnt && RES_TXTATR_FIELD != pAttr->Which()
154 return FALSE;
157 // !!! Die Content-Indizies beziehen sich immer auf den Node !!!
158 rRegion.GetPoint()->nNode = nMkNode.GetIndex() + 1;
159 SwCntntNode* pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, TRUE);
160 rRegion.GetPoint()->nContent.Assign(pCNd, nMkCntnt);
161 rRegion.SetMark();
162 if( nMkNode != nPtNode )
164 rRegion.GetPoint()->nNode = nPtNode.GetIndex() + 1;
165 pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, FALSE);
167 rRegion.GetPoint()->nContent.Assign(pCNd, nPtCntnt);
168 #if OSL_DEBUG_LEVEL > 1
169 ASSERT( CheckNodesRange( rRegion.Start()->nNode,
170 rRegion.End()->nNode, TRUE ),
171 "Attribut oder AEhnliches ueber Bereichs-Grenzen" );
172 #endif
173 if( bCheck )
174 return CheckNodesRange( rRegion.Start()->nNode,
175 rRegion.End()->nNode, TRUE );
176 else
177 return TRUE;
180 SwFltControlStack::SwFltControlStack(SwDoc* pDo, ULONG nFieldFl)
181 : nFieldFlags(nFieldFl), pDoc(pDo), bIsEndStack(false)
186 SwFltControlStack::~SwFltControlStack()
188 ASSERT(!Count(), "noch Attribute auf dem Stack");
191 // MoveAttrs() ist fuer folgendes Problem:
192 // Wenn ueber den Stack ein Feld wie z.B. "Variable setzen" gesetzt wird,
193 // verschiebt sich der Text um ein \xff - Zeichen, und alle folgenden
194 // Attribute stimmen in ihrer Position nicht mehr.
195 // Dann muss MoveAttrs() nach dem Setzen des Attributes ins Doc gerufen werden,
196 // so dass alle Attribut-Positionen,
197 // die im selben Absatz weiter hinten stehen, um 1 Zeichen weiter
198 // nach rechts verschoben werden.
199 void SwFltControlStack::MoveAttrs( const SwPosition& rPos )
201 USHORT nCnt = static_cast< USHORT >(Count());
202 SwFltStackEntry* pEntry;
203 ULONG nPosNd = rPos.nNode.GetIndex();
204 USHORT nPosCt = rPos.nContent.GetIndex() - 1;
206 for (USHORT i=0; i < nCnt; i++){
207 pEntry = (*this)[ i ];
208 if(( pEntry->nMkNode.GetIndex() + 1 == nPosNd )
209 &&( pEntry->nMkCntnt >= nPosCt )){
210 pEntry->nMkCntnt++;
211 ASSERT( pEntry->nMkCntnt
212 <= pDoc->GetNodes()[nPosNd]->GetCntntNode()->Len(),
213 "Attribut-Anfang hinter Zeilenende" );
215 if(( pEntry->nPtNode.GetIndex() + 1 == nPosNd )
216 &&( pEntry->nPtCntnt >= nPosCt )){
217 pEntry->nPtCntnt++;
218 ASSERT( pEntry->nPtCntnt
219 <= pDoc->GetNodes()[nPosNd]->GetCntntNode()->Len(),
220 "Attribut-Ende hinter Zeilenende" );
225 void SwFltControlStack::MarkAllAttrsOld()
227 USHORT nCnt = static_cast< USHORT >(Count());
228 for (USHORT i=0; i < nCnt; i++)
229 (*this)[ i ]->bOld = TRUE;
232 void SwFltControlStack::NewAttr(const SwPosition& rPos, const SfxPoolItem & rAttr )
234 SwFltStackEntry *pTmp = new SwFltStackEntry(rPos, rAttr.Clone() );
235 USHORT nWhich = pTmp->pAttr->Which();
236 SetAttr(rPos, nWhich);// Ende von evtl. gleichen Attributen auf dem Stack
237 // Setzen, damit sich die Attribute nicht auf
238 // dem Stack haeufen
239 maEntries.push_back(pTmp);
242 void SwFltControlStack::DeleteAndDestroy(Entries::size_type nCnt)
244 ASSERT(nCnt < maEntries.size(), "Out of range!");
245 if (nCnt < maEntries.size())
247 myEIter aElement = maEntries.begin() + nCnt;
248 delete *aElement;
249 maEntries.erase(aElement);
253 // SwFltControlStack::StealAttr() loescht Attribute des angegebenen Typs vom Stack.
254 // Als nAttrId sind erlaubt: 0 fuer alle, oder ein spezieller Typ.
255 // Damit erscheinen sie nicht in der Doc-Struktur. Dabei werden nur die
256 // Attribute entfernt, die im selben Absatz wie pPos stehen.
257 // Wird fuer Grafik-Apos -> Grafiken benutzt.
258 void SwFltControlStack::StealAttr(const SwPosition* pPos, USHORT nAttrId /* = 0 */)
260 USHORT nCnt = static_cast< USHORT >(Count());
262 SwFltStackEntry* pEntry;
264 while (nCnt)
266 nCnt --;
267 pEntry = (*this)[ nCnt ];
268 if (pEntry->nPtNode.GetIndex()+1 == pPos->nNode.GetIndex() &&
269 (!nAttrId || nAttrId == pEntry->pAttr->Which()))
270 DeleteAndDestroy(nCnt); // loesche aus dem Stack
274 // SwFltControlStack::KillUnlockedAttr() loescht alle Attribute vom Stack,
275 // welche punktuell auf pPos aufgespannt sind.
276 // Damit erscheinen sie nicht in der Doc-Struktur.
277 // Wird im WW Import benoetigt zum ignorieren der auf dem 0x0c Section-
278 // Break-Symbol gesetzten Attribute.
279 void SwFltControlStack::KillUnlockedAttrs(const SwPosition& pPos)
281 SwNodeIndex aAktNode( pPos.nNode, -1 );
282 USHORT nAktIdx = pPos.nContent.GetIndex();
284 USHORT nCnt = static_cast< USHORT >(Count());
285 SwFltStackEntry* pEntry;
286 while( nCnt )
288 nCnt --;
289 pEntry = (*this)[ nCnt ];
290 if( !pEntry->bOld
291 && !pEntry->bLocked
292 && (pEntry->nMkNode == aAktNode)
293 && (pEntry->nMkCntnt == nAktIdx )
294 && (pEntry->nPtNode == aAktNode)
295 && (pEntry->nPtCntnt == nAktIdx ))
297 DeleteAndDestroy( nCnt ); // loesche aus dem Stack
302 // Alle gelockten Attribute freigeben (unlocken) und das Ende setzen,
303 // alle anderen im Document setzen und wieder aus dem Stack loeschen
304 // Returned, ob das gesuchte Attribut / die gesuchten Attribute
305 // ueberhaupt auf dem Stack standen
306 void SwFltControlStack::SetAttr(const SwPosition& rPos, USHORT nAttrId,
307 BOOL bTstEnde, long nHand, BOOL consumedByField )
309 ASSERT(!nAttrId ||
310 (POOLATTR_BEGIN <= nAttrId && POOLATTR_END > nAttrId) ||
311 (RES_FLTRATTR_BEGIN <= nAttrId && RES_FLTRATTR_END > nAttrId),
312 "Falsche Id fuers Attribut")
314 USHORT nCnt = static_cast< USHORT >(Count());
316 SwFltStackEntry* pEntry;
318 for (USHORT i=0; i < nCnt; i++)
320 pEntry = (*this)[ i ];
321 if (pEntry->bLocked)
323 // setze das Ende vom Attribut
324 bool bF = false;
325 if (!nAttrId ){
326 bF = true;
327 }else if( nAttrId == pEntry->pAttr->Which()){
328 if( nAttrId != RES_FLTR_BOOKMARK ){ // Handle abfragen
329 bF = true;
330 }else if( nHand == ((SwFltBookmark*)(pEntry->pAttr))->GetHandle() )
332 bF = true;
335 if (bF) {
336 pEntry->bConsumedByField = consumedByField;
337 pEntry->SetEndPos(rPos);
339 continue;
342 // ist die Endposition die Cursor-Position, dann noch nicht
343 // ins Dokument setzen, es muss noch Text folgen;
344 // ausser am Dokumentende. (Attribut-Expandierung !!)
345 // Beim Ende-Stack niemals ausser am DocEnde reinsetzen
346 if (bTstEnde)
348 if (bIsEndStack || pEntry->nPtNode.GetIndex()+1 ==
349 rPos.nNode.GetIndex())
350 continue;
352 SetAttrInDoc(rPos, pEntry);
353 DeleteAndDestroy(i); // loesche aus dem Stack
354 i--; nCnt--; // Danach rutschen alle folgenden nach unten
358 static void MakePoint(SwFltStackEntry* pEntry, SwDoc* pDoc, SwPaM& rRegion)
360 // der Anker ist der Point vom Pam. Dieser wird beim Einfugen
361 // von Text usw. veraendert; darum wird er auf dem Stack
362 // gespeichert. Das Attribut muss nur noch im Format
363 // gesetzt werden.
364 rRegion.DeleteMark();
365 rRegion.GetPoint()->nNode = pEntry->nMkNode.GetIndex() + 1;
366 SwCntntNode* pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, TRUE);
367 rRegion.GetPoint()->nContent.Assign(pCNd, pEntry->nMkCntnt);
370 // MakeBookRegionOrPoint() ist wie MakeRegionOrPoint, aber die besonderen
371 // Beschraenkungen von Bookmarks in Tabellen werden beachtet.
372 // ( Anfang und Ende muessen in selber Zelle sein )
373 static void MakeBookRegionOrPoint(SwFltStackEntry* pEntry, SwDoc* pDoc,
374 SwPaM& rRegion, BOOL bCheck )
376 if (pEntry->MakeRegion(pDoc, rRegion, bCheck )){
377 const SwNodes& rNds = pDoc->GetNodes();
378 // BOOL b1 = rNds[rRegion.GetPoint()->nNode]->FindTableNode() != 0;
379 // const SwStartNode* p1 = rNds[rRegion.GetPoint()->nNode]->FindTableBoxStartNode();
380 // const SwStartNode* p2 = rNds[rRegion.GetMark()->nNode]->FindTableBoxStartNode();
381 if( rNds[rRegion.GetPoint()->nNode]->FindTableBoxStartNode()
382 != rNds[rRegion.GetMark()->nNode]->FindTableBoxStartNode() ){
383 rRegion.Exchange(); // Ungueltiger Bereich
384 rRegion.DeleteMark(); // -> beide auf Mark
386 }else{
387 MakePoint(pEntry, pDoc, rRegion);
391 #if OSL_DEBUG_LEVEL > 1
392 extern BOOL CheckNodesRange( const SwNodeIndex& rStt,
393 const SwNodeIndex& rEnd, BOOL bChkSection );
394 #endif
396 // IterateNumrulePiece() sucht von rTmpStart bis rEnd den ersten
397 // fuer Numrules gueltigen Bereich heraus.
399 // rNds sind die Doc-Nodes
400 // rEnd ist Bereichs-Ende,
401 // rTmpStart ist ReinRaus-Parameter: Anfang des zu untersuchenden Bereiches rein,
402 // Anfang des gueltigen Bereichs raus
403 // rTmpEnd ist raus-Parameter
404 // Return-Bool ist TRUE fuer gueltigen Bereich
405 static BOOL IterateNumrulePiece( const SwNodeIndex& rEnd,
406 SwNodeIndex& rTmpStart, SwNodeIndex& rTmpEnd )
408 while( ( rTmpStart <= rEnd )
409 && !( rTmpStart.GetNode().IsTxtNode() ) ) // suche gueltigen Anfang
410 rTmpStart++;
412 rTmpEnd = rTmpStart;
413 while( ( rTmpEnd <= rEnd )
414 && ( rTmpEnd.GetNode().IsTxtNode() ) ) // suche gueltiges Ende + 1
415 rTmpEnd++;
417 rTmpEnd--; // gueltiges Ende
419 return rTmpStart <= rTmpEnd; // gueltig ?
422 void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos, SwFltStackEntry* pEntry)
424 SwPaM aRegion( rTmpPos );
426 switch(pEntry->pAttr->Which())
428 case RES_FLTR_ANCHOR:
430 SwFrmFmt* pFmt = ((SwFltAnchor*)pEntry->pAttr)->GetFrmFmt();
431 if (pFmt != NULL)
433 MakePoint(pEntry, pDoc, aRegion);
434 SwFmtAnchor aAnchor(pFmt->GetAnchor());
435 aAnchor.SetAnchor(aRegion.GetPoint());
436 pFmt->SetFmtAttr(aAnchor);
437 // Damit die Frames bei Einfuegen in existierendes Doc
438 // erzeugt werden (erst nach Setzen des Ankers!):
439 if(pDoc->GetRootFrm()
440 && FLY_AT_CNTNT == pFmt->GetAnchor().GetAnchorId())
442 pFmt->MakeFrms();
446 break;
447 case RES_FLTR_STYLESHEET:
448 break;
449 case RES_TXTATR_FIELD:
450 break;
451 case RES_TXTATR_TOXMARK:
452 break;
453 case RES_FLTR_NUMRULE: // Numrule 'reinsetzen
455 const String& rNumNm = ((SfxStringItem*)pEntry->pAttr)->GetValue();
456 SwNumRule* pRul = pDoc->FindNumRulePtr( rNumNm );
457 if( pRul )
459 if( pEntry->MakeRegion(pDoc, aRegion, TRUE))
461 SwNodeIndex aTmpStart( aRegion.Start()->nNode );
462 SwNodeIndex aTmpEnd( aTmpStart );
463 SwNodeIndex& rRegEndNd = aRegion.End()->nNode;
464 while( IterateNumrulePiece( rRegEndNd,
465 aTmpStart, aTmpEnd ) )
467 SwPaM aTmpPam( aTmpStart, aTmpEnd );
468 // --> OD 2008-03-17 #refactorlists#
469 // no start of a new list
470 pDoc->SetNumRule( aTmpPam, *pRul, false );
471 // <--
473 aTmpStart = aTmpEnd; // Start fuer naechstes Teilstueck
474 aTmpStart++;
477 else
478 pDoc->DelNumRule( rNumNm );
481 break;
482 case RES_FLTR_NUMRULE_NUM:
483 break;
484 case RES_FLTR_BOOKMARK: // eigentlich nur fuer den Ende-Stack
486 SwFltBookmark* pB = (SwFltBookmark*)pEntry->pAttr;
487 const String& rName = ((SwFltBookmark*)pEntry->pAttr)->GetName();
489 if (IsFlagSet(BOOK_TO_VAR_REF))
491 if (pB->IsPgRef() && !pB->IsRef())
493 // XRefs und Bookmarks sind bereits geUpcased
494 MakeBookRegionOrPoint(pEntry, pDoc, aRegion, TRUE);
495 pDoc->InsertPoolItem(aRegion, SwFmtRefMark(rName), 0);
497 else if( !pB->IsOnlyRef() )
499 SwFieldType* pFT = pDoc->GetFldType(RES_SETEXPFLD, rName, false);
500 if (!pFT)
501 { // FieldType anlegen
502 SwSetExpFieldType aS(pDoc, rName, nsSwGetSetExpType::GSE_STRING);
503 pFT = pDoc->InsertFldType(aS);
505 SwSetExpField aFld((SwSetExpFieldType*)pFT,
506 pB->GetValSys());
507 aFld.SetSubType( nsSwExtendedSubType::SUB_INVISIBLE );
508 MakePoint(pEntry, pDoc, aRegion);
509 pDoc->InsertPoolItem(aRegion, SwFmtFld(aFld), 0);
510 MoveAttrs( *(aRegion.GetPoint()) );
513 if( !pB->IsOnlyRef() &&
514 ( !IsFlagSet(HYPO) || IsFlagSet(BOOK_AND_REF) ) && !pEntry->bConsumedByField)
516 MakeBookRegionOrPoint(pEntry, pDoc, aRegion, TRUE);
517 pDoc->getIDocumentMarkAccess()->makeMark( aRegion, rName, IDocumentMarkAccess::BOOKMARK);
520 break;
521 case RES_FLTR_TOX:
523 MakePoint(pEntry, pDoc, aRegion);
525 SwPosition* pPoint = aRegion.GetPoint();
527 SwFltTOX* pTOXAttr = (SwFltTOX*)pEntry->pAttr;
529 // test if on this node there had been a pagebreak BEFORE the
530 // tox attribut was put on the stack
531 SfxItemSet aBkSet( pDoc->GetAttrPool(), RES_PAGEDESC, RES_BREAK );
532 SwCntntNode* pNd = 0;
533 if( !pTOXAttr->HadBreakItem() || !pTOXAttr->HadPageDescItem() )
535 pNd = pPoint->nNode.GetNode().GetCntntNode();
536 if( pNd )
538 const SfxItemSet* pSet = pNd->GetpSwAttrSet();
539 const SfxPoolItem* pItem;
540 if( pSet )
542 if( !pTOXAttr->HadBreakItem()
543 && SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, FALSE, &pItem ) )
545 aBkSet.Put( *pItem );
546 pNd->ResetAttr( RES_BREAK );
548 if( !pTOXAttr->HadPageDescItem()
549 && SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, FALSE, &pItem ) )
551 aBkSet.Put( *pItem );
552 pNd->ResetAttr( RES_PAGEDESC );
558 delete pTOXAttr->GetBase();
560 // set (aboved saved and removed) the break item at the node following the TOX
561 if( aBkSet.Count() )
562 pNd->SetAttr( aBkSet );
564 break;
565 case RES_FLTR_SECTION:
566 MakePoint(pEntry, pDoc, aRegion); // bislang immer Point==Mark
567 pDoc->InsertSwSection(aRegion,
568 *(static_cast<SwFltSection*>(pEntry->pAttr))->GetSection(),
569 0, false);
570 delete(((SwFltSection*)pEntry->pAttr)->GetSection());
571 break;
572 case RES_FLTR_REDLINE:
574 if (pEntry->MakeRegion(pDoc, aRegion, TRUE))
576 pDoc->SetRedlineMode((RedlineMode_t)( nsRedlineMode_t::REDLINE_ON
577 | nsRedlineMode_t::REDLINE_SHOW_INSERT
578 | nsRedlineMode_t::REDLINE_SHOW_DELETE ));
579 SwFltRedline& rFltRedline = *((SwFltRedline*)pEntry->pAttr);
581 if( USHRT_MAX != rFltRedline.nAutorNoPrev )
583 SwRedlineData aData(rFltRedline.eTypePrev,
584 rFltRedline.nAutorNoPrev,
585 rFltRedline.aStampPrev,
586 aEmptyStr,
589 pDoc->AppendRedline(new SwRedline(aData, aRegion), true);
591 SwRedlineData aData(rFltRedline.eType,
592 rFltRedline.nAutorNo,
593 rFltRedline.aStamp,
594 aEmptyStr,
597 pDoc->AppendRedline( new SwRedline(aData, aRegion), true );
598 pDoc->SetRedlineMode((RedlineMode_t)( nsRedlineMode_t::REDLINE_NONE
599 | nsRedlineMode_t::REDLINE_SHOW_INSERT
600 | nsRedlineMode_t::REDLINE_SHOW_DELETE ));
603 break;
604 default:
605 if (pEntry->MakeRegion(pDoc, aRegion, FALSE))
607 pDoc->InsertPoolItem(aRegion, *pEntry->pAttr, 0);
609 break;
613 SfxPoolItem* SwFltControlStack::GetFmtStackAttr(USHORT nWhich, USHORT * pPos)
615 SwFltStackEntry* pEntry;
616 USHORT nSize = static_cast< USHORT >(Count());
618 while (nSize)
620 // ist es das gesuchte Attribut ? (gueltig sind nur gelockte,
621 // also akt. gesetzte Attribute!!)
622 if ((pEntry = (*this)[ --nSize ])->bLocked &&
623 pEntry->pAttr->Which() == nWhich)
625 if (pPos)
626 *pPos = nSize;
627 return (SfxPoolItem*)pEntry->pAttr; // Ok, dann Ende
630 return 0;
633 const SfxPoolItem* SwFltControlStack::GetFmtAttr(const SwPosition& rPos, USHORT nWhich)
635 SfxPoolItem* pHt = GetFmtStackAttr(nWhich);
636 if (pHt)
637 return (const SfxPoolItem*)pHt;
639 // im Stack ist das Attribut nicht vorhanden, also befrage das Dokument
640 // SwCntntNode * pNd = rPaM.GetCntntNode();
641 SwCntntNode * pNd = pDoc->GetNodes()[ rPos.nNode ]->GetCntntNode();
643 if (!pNd) // kein ContentNode, dann das dflt. Attribut
644 return &pDoc->GetAttrPool().GetDefaultItem(nWhich);
645 return &pNd->GetAttr(nWhich);
648 void SwFltControlStack::Delete(const SwPaM &rPam)
650 const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
652 if( !rPam.HasMark() || *pStt >= *pEnd )
653 return;
655 SwNodeIndex aStartNode(pStt->nNode, -1);
656 USHORT nStartIdx = pStt->nContent.GetIndex();
657 SwNodeIndex aEndNode(pEnd->nNode, -1);
658 USHORT nEndIdx = pEnd->nContent.GetIndex();
660 //We don't support deleting content that is over one node, or removing a node.
661 ASSERT(aEndNode == aStartNode, "nodes must be the same, or this method extended");
662 if (aEndNode != aStartNode)
663 return;
665 for (USHORT nSize = static_cast< USHORT >(Count()); nSize > 0;)
667 SwFltStackEntry* pEntry = (*this)[--nSize];
669 bool bEntryStartAfterSelStart =
670 (pEntry->nMkNode == aStartNode && pEntry->nMkCntnt >= nStartIdx);
672 bool bEntryStartBeforeSelEnd =
673 (pEntry->nMkNode == aEndNode && pEntry->nMkCntnt <= nEndIdx);
675 bool bEntryEndAfterSelStart = false;
676 bool bEntryEndBeforeSelEnd = false;
677 if (!pEntry->bLocked)
679 bEntryEndAfterSelStart =
680 (pEntry->nPtNode == aStartNode && pEntry->nPtCntnt >= nStartIdx);
682 bEntryEndBeforeSelEnd =
683 (pEntry->nPtNode == aEndNode && pEntry->nPtCntnt <= nEndIdx);
686 bool bTotallyContained = false;
687 if (
688 bEntryStartAfterSelStart && bEntryStartBeforeSelEnd &&
689 bEntryEndAfterSelStart && bEntryEndBeforeSelEnd
692 bTotallyContained = true;
695 if (bTotallyContained)
697 //after start, before end, delete
698 DeleteAndDestroy(nSize);
699 continue;
702 xub_StrLen nCntntDiff = nEndIdx - nStartIdx;
704 //to be adjusted
705 if (bEntryStartAfterSelStart)
707 if (bEntryStartBeforeSelEnd)
709 //move start to new start
710 pEntry->nMkNode = aStartNode;
711 pEntry->nMkCntnt = nStartIdx;
713 else
714 pEntry->nMkCntnt = pEntry->nMkCntnt - nCntntDiff;
717 if (bEntryEndAfterSelStart)
719 if (bEntryEndBeforeSelEnd)
721 pEntry->nPtNode = aStartNode;
722 pEntry->nPtCntnt = nStartIdx;
724 else
725 pEntry->nPtCntnt = pEntry->nPtCntnt - nCntntDiff;
728 //That's what locked is, end equal to start, and nPtCntnt is invalid
729 if (pEntry->bLocked)
730 pEntry->nPtNode = pEntry->nMkNode;
734 //------ hier stehen die Methoden von SwFltAnchor -----------
735 SwFltAnchor::SwFltAnchor(SwFrmFmt* pFmt) :
736 SfxPoolItem(RES_FLTR_ANCHOR), pFrmFmt(pFmt)
738 pClient = new SwFltAnchorClient(this);
739 pFrmFmt->Add(pClient);
742 SwFltAnchor::SwFltAnchor(const SwFltAnchor& rCpy) :
743 SfxPoolItem(RES_FLTR_ANCHOR), pFrmFmt(rCpy.pFrmFmt)
745 pClient = new SwFltAnchorClient(this);
746 pFrmFmt->Add(pClient);
749 SwFltAnchor::~SwFltAnchor()
751 delete pClient;
754 void SwFltAnchor::SetFrmFmt(SwFrmFmt * _pFrmFmt)
756 pFrmFmt = _pFrmFmt;
759 const SwFrmFmt * SwFltAnchor::GetFrmFmt() const
761 return pFrmFmt;
764 SwFrmFmt * SwFltAnchor::GetFrmFmt()
766 return pFrmFmt;
769 int SwFltAnchor::operator==(const SfxPoolItem& rItem) const
771 return pFrmFmt == ((SwFltAnchor&)rItem).pFrmFmt;
774 SfxPoolItem* __EXPORT SwFltAnchor::Clone(SfxItemPool*) const
776 return new SwFltAnchor(*this);
779 // SwFltAnchorClient
781 SwFltAnchorClient::SwFltAnchorClient(SwFltAnchor * pFltAnchor)
782 : m_pFltAnchor(pFltAnchor)
786 void SwFltAnchorClient::Modify(SfxPoolItem *, SfxPoolItem * pNew)
788 if (pNew->Which() == RES_FMT_CHG)
790 SwFmtChg * pFmtChg = dynamic_cast<SwFmtChg *> (pNew);
792 if (pFmtChg != NULL)
794 SwFrmFmt * pFrmFmt = dynamic_cast<SwFrmFmt *> (pFmtChg->pChangedFmt);
796 if (pFrmFmt != NULL)
797 m_pFltAnchor->SetFrmFmt(pFrmFmt);
802 //------ hier stehen die Methoden von SwFltRedline -----------
803 int SwFltRedline::operator==(const SfxPoolItem& rItem) const
805 return this == &rItem;
808 SfxPoolItem* SwFltRedline::Clone( SfxItemPool* ) const
810 return new SwFltRedline(*this);
813 //------ hier stehen die Methoden von SwFltBookmark -----------
814 SwFltBookmark::SwFltBookmark( const String& rNa, const String& rVa,
815 long nHand, BOOL bOnlyR )
816 : SfxPoolItem(RES_FLTR_BOOKMARK), nHandle(nHand), aName(rNa), aVal(rVa),
817 bOnlyRef(bOnlyR), bRef(FALSE), bPgRef(FALSE)
819 // eSrc: CHARSET_DONTKNOW fuer keine UEbersetzung bei operator <<
820 // Upcase wird immer gemacht.
821 // bei XXXStack.NewAttr(...) wird nie eine UEbersetzung vorgenommen.
822 // ansonsten: uebergebener Src-Charset fuer aName
823 // im Filter eingestellter Src-Charset fuer aVal ( Text )
826 SwFltBookmark::SwFltBookmark(const SwFltBookmark& rCpy)
827 : SfxPoolItem(RES_FLTR_BOOKMARK),
828 nHandle(rCpy.nHandle),
829 aName(rCpy.aName),
830 aVal(rCpy.aVal),
831 bOnlyRef(rCpy.bOnlyRef),
832 bRef(rCpy.bRef),
833 bPgRef(rCpy.bPgRef)
837 int SwFltBookmark::operator==(const SfxPoolItem& rItem) const
839 return (aName == ((SwFltBookmark&)rItem).aName)
840 && (nHandle == ((SwFltBookmark&)rItem).nHandle);
843 SfxPoolItem* SwFltBookmark::Clone(SfxItemPool*) const
845 return new SwFltBookmark(*this);
848 //------ hier stehen die Methoden von SwFltTOX -----------
850 SwFltTOX::SwFltTOX(SwTOXBase* pBase, USHORT _nCols)
851 : SfxPoolItem(RES_FLTR_TOX), pTOXBase(pBase), nCols( _nCols ),
852 bHadBreakItem( FALSE ), bHadPageDescItem( FALSE )
856 SwFltTOX::SwFltTOX(const SwFltTOX& rCpy)
857 : SfxPoolItem(RES_FLTR_TOX), pTOXBase(rCpy.pTOXBase), nCols( rCpy.nCols ),
858 bHadBreakItem( rCpy.bHadBreakItem ), bHadPageDescItem( rCpy.bHadPageDescItem )
862 int SwFltTOX::operator==(const SfxPoolItem& rItem) const
864 return pTOXBase == ((SwFltTOX&)rItem).pTOXBase;
867 SfxPoolItem* SwFltTOX::Clone(SfxItemPool*) const
869 return new SwFltTOX(*this);
872 //------ hier stehen die Methoden von SwFltSwSection -----------
874 SwFltSection::SwFltSection(SwSection *pSect) :
875 SfxPoolItem(RES_FLTR_SECTION), pSection(pSect)
879 SwFltSection::SwFltSection(const SwFltSection& rCpy) :
880 SfxPoolItem(RES_FLTR_SECTION), pSection(rCpy.pSection)
884 int SwFltSection::operator==(const SfxPoolItem& rItem) const
886 return pSection == ((SwFltSection&)rItem).pSection;
889 SfxPoolItem* __EXPORT SwFltSection::Clone(SfxItemPool*) const
891 return new SwFltSection(*this);
894 ///////////////////////////////////////////////////////////////////////
896 // hier beginnt der von mdt erzeugte code. dieser ist eine shell auf
897 // der writer-seite nach moeglichkeit bald fuer alle filter. die ganze
898 // schwierigkeit, texte & formatattribute einzufuegen, die positionen
899 // zu verwalten, styles & kopf/fuszzeilen etc.
902 //////////////////////////////////////////////////////////// SwFltShell
903 SwFltShell::SwFltShell(SwDoc* pDoc, SwPaM& rPaM, const String& rBaseURL, BOOL bNew, ULONG nFieldFl) :
904 pCurrentPageDesc(0),
905 pSavedPos(0),
906 eSubMode(None),
907 nAktStyle(0),
908 aStack(pDoc, nFieldFl),
909 aEndStack(pDoc, nFieldFl),
910 pPaM(new SwPaM(*(rPaM.GetPoint()))),
911 sBaseURL(rBaseURL),
912 nPageDescOffset(GetDoc().GetPageDescCnt()),
913 eSrcCharSet(RTL_TEXTENCODING_MS_1252),
914 bNewDoc(bNew),
915 bStdPD(FALSE),
916 bProtect(FALSE)
918 memset( pColls, 0, sizeof( pColls ) );
919 pOutDoc = new SwFltOutDoc( *pDoc, pPaM, aStack, aEndStack );
920 pOut = pOutDoc;
922 if( !bNewDoc ){ // in ein Dokument einfuegen ?
923 // Da immer ganze Zeile eingelesen werden, muessen
924 // evtl. Zeilen eingefuegt / aufgebrochen werden
925 const SwPosition* pPos = pPaM->GetPoint();
926 const SwTxtNode* pSttNd = pPos->nNode.GetNode().GetTxtNode();
927 USHORT nCntPos = pPos->nContent.GetIndex();
928 if( nCntPos && pSttNd->GetTxt().Len() )
929 // EinfuegePos nicht in leerer Zeile
930 pDoc->SplitNode( *pPos, false ); // neue Zeile erzeugen
931 if( pSttNd->GetTxt().Len() ){ // EinfuegePos nicht am Ende der Zeile
932 pDoc->SplitNode( *pPos, false ); // neue Zeile
933 pPaM->Move( fnMoveBackward ); // gehe in leere Zeile
936 // verhinder das Einlesen von Tabellen in Fussnoten / Tabellen
937 ULONG nNd = pPos->nNode.GetIndex();
938 BOOL bReadNoTbl = 0 != pSttNd->FindTableNode() ||
939 ( nNd < pDoc->GetNodes().GetEndOfInserts().GetIndex() &&
940 pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() < nNd );
941 if( bReadNoTbl )
942 pOutDoc->SetReadNoTable();
944 pCurrentPageDesc = &((SwPageDesc&)const_cast<const SwDoc *>(pDoc)
945 ->GetPageDesc( 0 )); // Standard
949 SwFltShell::~SwFltShell()
951 USHORT i;
953 if (eSubMode == Style)
954 EndStyle();
955 if( pOutDoc->IsInTable() ) // falls nicht ordentlich abgeschlossen
956 EndTable();
957 if( pOutDoc->IsInFly() )
958 EndFly();
960 GetDoc().SetUpdateExpFldStat(true);
961 GetDoc().SetInitDBFields(TRUE);
962 aStack.SetAttr(*pPaM->GetPoint(), 0, FALSE);
963 aStack.SetAttr(*pPaM->GetPoint(), 0, FALSE);
964 aEndStack.SetAttr(*pPaM->GetPoint(), 0, FALSE);
965 aEndStack.SetAttr(*pPaM->GetPoint(), 0, FALSE);
966 if( bProtect ){ // Das ganze Doc soll geschuetzt sein
968 SwDoc& rDoc = GetDoc();
969 // 1. SectionFmt und Section anlegen
970 SwSectionFmt* pSFmt = rDoc.MakeSectionFmt( 0 );
971 SwSection aS( CONTENT_SECTION, String::CreateFromAscii(
972 RTL_CONSTASCII_STRINGPARAM("PMW-Protect") ));
973 aS.SetProtect( TRUE );
974 // 2. Start- und EndIdx suchen
975 const SwNode* pEndNd = &rDoc.GetNodes().GetEndOfContent();
976 SwNodeIndex aEndIdx( *pEndNd, -1L );
977 const SwStartNode* pSttNd = pEndNd->StartOfSectionNode();
978 SwNodeIndex aSttIdx( *pSttNd, 1L ); // +1 -> hinter StartNode
979 // Section einfuegen
980 // Section einfuegen
981 rDoc.GetNodes().InsertSection( aSttIdx, *pSFmt, aS, &aEndIdx, FALSE );
983 if( !IsFlagSet(SwFltControlStack::DONT_HARD_PROTECT) ){
984 SwDocShell* pDocSh = rDoc.GetDocShell();
985 if( pDocSh )
986 pDocSh->SetReadOnlyUI( TRUE );
989 // Pagedescriptoren am Dokument updaten (nur so werden auch die
990 // linken Seiten usw. eingestellt).
992 GetDoc().ChgPageDesc( 0,
993 const_cast<const SwDoc &>(GetDoc()).
994 GetPageDesc( 0 )); // PageDesc "Standard"
995 for (i=nPageDescOffset;i<GetDoc().GetPageDescCnt();i++)
997 const SwPageDesc& rPD = const_cast<const SwDoc &>(GetDoc()).
998 GetPageDesc(i);
999 GetDoc().ChgPageDesc(i, rPD);
1002 delete pPaM;
1003 for (i=0; i<sizeof(pColls)/sizeof(*pColls); i++)
1004 if( pColls[i] )
1005 delete pColls[i];
1006 delete pOutDoc;
1009 SwFltShell& SwFltShell::operator << ( const String& rStr )
1011 ASSERT(eSubMode != Style, "char insert while in style-mode");
1012 GetDoc().InsertString( *pPaM, rStr );
1013 return *this;
1016 void SwFltShell::ConvertUStr( String& rInOut )
1018 GetAppCharClass().toUpper( rInOut );
1021 // QuoteString() wandelt CRs abhaengig von nFieldIniFlags in '\n' oder "\0x0d"
1022 String SwFltShell::QuoteStr( const String& rIn )
1024 String sOut( rIn );
1025 BOOL bAllowCr = aStack.IsFlagSet( SwFltControlStack::ALLOW_FLD_CR );
1027 for( xub_StrLen n = 0; n < sOut.Len(); ++n )
1029 switch( sOut.GetChar( n ) )
1031 case 0x0a:
1032 sOut.Erase( n, 1 ); // 0xd 0xa wird zu \n
1033 break;
1035 case 0x0b:
1036 case 0x0c:
1037 case 0x0d:
1038 if( bAllowCr )
1039 sOut.SetChar( n, '\n' );
1040 break;
1043 return sOut;
1046 SwFltShell& SwFltShell::operator << ( const sal_Unicode c )
1048 ASSERT( eSubMode != Style, "char insert while in style-mode");
1049 GetDoc().InsertString( *pPaM, c );
1050 return *this;
1053 SwFltShell& SwFltShell::AddError( const sal_Char* pErr )
1055 String aName( String::CreateFromAscii(
1056 RTL_CONSTASCII_STRINGPARAM( "ErrorTag" )));
1057 SwFieldType* pFT = GetDoc().GetFldType( RES_SETEXPFLD, aName, false );
1058 if( pFT == 0)
1060 SwSetExpFieldType aS(&GetDoc(), aName, nsSwGetSetExpType::GSE_STRING);
1061 pFT = GetDoc().InsertFldType(aS);
1063 SwSetExpField aFld( (SwSetExpFieldType*)pFT,
1064 String::CreateFromAscii( pErr ));
1065 //, VVF_INVISIBLE
1066 GetDoc().InsertPoolItem(*pPaM, SwFmtFld(aFld), 0);
1067 return *this;
1070 SwFltShell& SwFltShell::operator << (Graphic& rGraphic)
1072 // embedded Grafik !!
1073 GetDoc().Insert(*pPaM, aEmptyStr, aEmptyStr, &rGraphic, NULL, NULL, NULL);
1074 return *this;
1077 void SwFltShell::NextParagraph()
1079 GetDoc().AppendTxtNode(*pPaM->GetPoint());
1082 void SwFltShell::NextPage()
1084 NextParagraph();
1085 GetDoc().InsertPoolItem(*pPaM,
1086 SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK), 0);
1089 SwFltShell& SwFltShell::AddGraphic( const String& rPicName )
1091 // embedded:
1092 GraphicFilter* pFilter = ::GetGrfFilter();
1093 Graphic aGraphic;
1094 // one of: GFF_NOT GFF_BMP GFF_GIF GFF_JPG GFF_PCD GFF_PCX GFF_PNG
1095 // GFF_TIF GFF_XBM GFF_DXF GFF_MET GFF_PCT GFF_SGF GFF_SVM GFF_WMF
1096 // GFF_SGV GFF_XXX
1097 INetURLObject aDir(
1098 URIHelper::SmartRel2Abs(
1099 INetURLObject(GetBaseURL()), rPicName,
1100 URIHelper::GetMaybeFileHdl()) );
1101 switch (pFilter->ImportGraphic(aGraphic, aDir))
1103 case GRFILTER_OK:
1104 *this << aGraphic;
1105 break;
1106 case GRFILTER_OPENERROR:
1107 case GRFILTER_IOERROR:
1108 case GRFILTER_FORMATERROR:
1109 case GRFILTER_VERSIONERROR:
1110 case GRFILTER_FILTERERROR:
1111 case GRFILTER_ABORT:
1112 case GRFILTER_TOOBIG:
1113 default:
1114 AddError( "picture import error" );
1115 break;
1117 return *this;
1120 SwFltShell& SwFltShell::SetStyle( USHORT nStyle )
1122 SwFltFormatCollection* p = pColls[ nStyle ];
1124 if (p)
1126 if( !pOutDoc->IsInTable() && nStyle != nAktStyle )
1128 if( pColls[nAktStyle]->IsInFly() && pOutDoc->IsInFly() )
1129 pOutDoc->EndFly();
1130 if( p->IsInFly() )
1131 p->BeginStyleFly( pOutDoc );
1133 GetDoc().SetTxtFmtColl(*pPaM, p->GetColl());
1134 nAktStyle = nStyle;
1136 else
1138 ASSERT( FALSE, "Ungueltiger SwFltStyleCode" );
1140 return *this;
1143 SwFltShell& SwFltShell::operator << (SwFltBookmark& aBook)
1145 ConvertUStr( aBook.aName );
1146 aBook.aVal = QuoteStr(aBook.aVal);
1147 aEndStack.NewAttr(*pPaM->GetPoint(), aBook);
1148 return *this;
1151 void SwFltShell::SetBookEnd(long nHandle)
1153 aEndStack.SetAttr( *pPaM->GetPoint(), RES_FLTR_BOOKMARK, TRUE, nHandle );
1156 SwFltShell& SwFltShell::EndItem( USHORT nAttrId )
1158 switch( nAttrId )
1160 case RES_FLTR_BOOKMARK:
1161 ASSERT( FALSE, "Falscher Aufruf fuer Bookmark-Ende" );
1162 break;
1164 case RES_FLTR_TOX:
1165 aEndStack.SetAttr(*pPaM->GetPoint(), nAttrId);
1166 break;
1168 default:
1169 aStack.SetAttr(*pPaM->GetPoint(), nAttrId);
1170 break;
1172 return *this;
1175 SwFltShell& SwFltShell::operator << (const SwField& rField)
1177 GetDoc().InsertPoolItem(*pPaM, SwFmtFld(rField), 0);
1178 return *this;
1181 /*virtual*/ SwFltOutBase& SwFltOutDoc::operator << (const SfxPoolItem& rItem)
1183 rStack.NewAttr(*pPaM->GetPoint(), rItem);
1184 return *this;
1187 /*virtual*/ SwFltOutBase& SwFltFormatCollection::operator <<
1188 (const SfxPoolItem& rItem)
1190 pColl->SetFmtAttr(rItem);
1191 return *this;
1194 const SfxPoolItem& SwFltOutDoc::GetAttr(USHORT nWhich)
1196 return *rStack.GetFmtAttr(*pPaM->GetPoint(), nWhich);
1199 const SfxPoolItem& SwFltFormatCollection::GetAttr(USHORT nWhich)
1201 return GetColl()->GetFmtAttr(nWhich); // mit Parents
1204 // GetNodeOrStyAttr holt Attribute fuer Toggle- und Modify-Attribute:
1205 // Bei Formatdefinitionen aus dem altuellen Style mit Parents
1206 // sonst aus dem Node mit Parents
1207 // Im Stack wird nicht nachgesehen
1209 const SfxPoolItem& SwFltOutDoc::GetNodeOrStyAttr(USHORT nWhich)
1211 SwCntntNode * pNd = GetDoc().GetNodes()[ pPaM->GetPoint()->nNode ]
1212 ->GetCntntNode();
1213 if (pNd) // ContentNode: Attribut mit Parent
1214 return pNd->GetAttr(nWhich);
1215 else // kein ContentNode, dann das dflt. Attribut
1216 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1219 const SfxPoolItem& SwFltFormatCollection::GetNodeOrStyAttr(USHORT nWhich)
1221 return GetColl()->GetFmtAttr(nWhich); // mit Parents
1224 const SfxPoolItem& SwFltShell::GetNodeOrStyAttr(USHORT nWhich)
1226 return pOut->GetNodeOrStyAttr( nWhich );
1229 const SfxPoolItem& SwFltShell::GetAttr(USHORT nWhich)
1231 return pOut->GetAttr( nWhich );
1234 const SfxPoolItem& SwFltShell::GetFlyFrmAttr(USHORT nWhich)
1236 return pOut->GetFlyFrmAttr( nWhich );
1239 SwFieldType* SwFltShell::GetSysFldType(USHORT eWhich)
1241 return GetDoc().GetSysFldType(eWhich);
1244 BOOL SwFltShell::GetWeightBold()
1246 return ((SvxWeightItem&)GetNodeOrStyAttr(RES_CHRATR_WEIGHT)).GetWeight()
1247 != WEIGHT_NORMAL;
1250 BOOL SwFltShell::GetPostureItalic()
1252 return ((SvxPostureItem&)GetNodeOrStyAttr(RES_CHRATR_POSTURE)).GetPosture()
1253 != ITALIC_NONE;
1256 BOOL SwFltShell::GetCrossedOut()
1258 return ((SvxCrossedOutItem&)GetNodeOrStyAttr(RES_CHRATR_CROSSEDOUT))
1259 .GetStrikeout() != STRIKEOUT_NONE;
1262 BOOL SwFltShell::GetContour()
1264 return ((SvxContourItem&)GetNodeOrStyAttr(RES_CHRATR_CONTOUR)).GetValue();
1267 BOOL SwFltShell::GetCaseKapitaelchen()
1269 return ((SvxCaseMapItem&)GetNodeOrStyAttr(RES_CHRATR_CASEMAP))
1270 .GetCaseMap() == SVX_CASEMAP_KAPITAELCHEN;
1273 BOOL SwFltShell::GetCaseVersalien()
1275 return ((SvxCaseMapItem&)GetNodeOrStyAttr(RES_CHRATR_CASEMAP))
1276 .GetCaseMap() == SVX_CASEMAP_VERSALIEN;
1279 //-------------------------------------------------------------------------
1280 // Tabellen
1281 //-------------------------------------------------------------------------
1283 SwFltOutBase::~SwFltOutBase()
1287 SwFltOutBase::SwFltOutBase(SwDoc& rDocu)
1288 : rDoc(rDocu), eFlyAnchor(FLY_AT_CNTNT), bFlyAbsPos(false)
1292 const SfxPoolItem& SwFltOutBase::GetCellAttr(USHORT nWhich)
1294 ASSERT(FALSE, "GetCellAttr ausserhalb von normalem Text");
1295 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1298 BOOL SwFltOutBase::BeginTable()
1300 ASSERT(FALSE, "BeginTable ausserhalb von normalem Text");
1301 return FALSE;
1304 void SwFltOutBase::NextTableCell()
1306 ASSERT(FALSE, "NextTableCell ausserhalb von normalem Text");
1309 void SwFltOutBase::NextTableRow()
1311 ASSERT(FALSE, "NextTableRow ausserhalb von normalem Text");
1314 void SwFltOutBase::SetTableWidth(SwTwips /*nW*/)
1316 ASSERT(FALSE, "SetTableWidth ausserhalb von normalem Text");
1319 void SwFltOutBase::SetTableOrient(sal_Int16 /*eOri*/)
1321 ASSERT(FALSE, "SetTableOrient ausserhalb von normalem Text");
1324 void SwFltOutBase::SetCellWidth(SwTwips /*nWidth*/, USHORT /*nCell*/)
1326 ASSERT(FALSE, "SetCellWidth ausserhalb von normalem Text");
1329 void SwFltOutBase::SetCellHeight(SwTwips /*nH*/)
1331 ASSERT(FALSE, "SetCellHeight ausserhalb von normalem Text");
1334 void SwFltOutBase::SetCellBorder(const SvxBoxItem& /*rFmtBox*/, USHORT /*nCell*/)
1336 ASSERT(FALSE, "SetCellBorder ausserhalb von normalem Text");
1339 void SwFltOutBase::SetCellSpace(USHORT /*nSp*/)
1341 ASSERT(FALSE, "SetCellSpace ausserhalb von normalem Text");
1344 void SwFltOutBase::DeleteCell(USHORT /*nCell*/)
1346 ASSERT(FALSE, "DeleteCell ausserhalb von normalem Text");
1349 void SwFltOutBase::EndTable()
1351 ASSERT(FALSE, "EndTable ausserhalb von normalem Text");
1354 /*virtual*/ BOOL SwFltOutDoc::IsInTable()
1356 return pTable != 0;
1359 BOOL SwFltOutDoc::BeginTable()
1361 if(bReadNoTbl)
1362 return FALSE;
1364 if (pTable){
1365 ASSERT(FALSE, "BeginTable in Table");
1366 return FALSE;
1368 // Alle Attribute schliessen, da sonst Attribute
1369 // entstehen koennen, die in Flys reinragen
1370 rStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1371 rEndStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1373 // create table:
1374 ASSERT(pTabSavedPos == NULL, "SwFltOutDoc");
1375 pTabSavedPos = new SwPosition(*pPaM->GetPoint());
1376 pTable = GetDoc().InsertTable(
1377 SwInsertTableOptions( tabopts::HEADLINE_NO_BORDER, 1 ),
1378 *pTabSavedPos, 1, 1, text::HoriOrientation::LEFT, 0, 0, FALSE, FALSE ); // TODO MULTIHEADER
1379 nTableWidth = 0;
1380 ((SwTable*)pTable)->LockModify(); // Nichts automatisch anpassen!
1381 // set pam in 1. table cell
1382 usTableX =
1383 usTableY = 0;
1384 SeekCell(usTableY, usTableX, TRUE);
1385 return TRUE;
1388 SwTableBox* SwFltOutDoc::GetBox(USHORT ny, USHORT nx /*= USHRT_MAX */)
1390 if(!pTable){
1391 ASSERT(pTable, "GetBox ohne Tabelle");
1392 return 0;
1394 if( nx == USHRT_MAX ) // aktuelle Zelle
1395 nx = usTableX;
1397 // get structs to table cells
1398 const SwTableLines* pTableLines = &pTable->GetTabLines();
1399 if(!pTableLines){
1400 ASSERT(FALSE, "SwFltOutDoc:GetBox:pTableLines");
1401 return 0;
1403 if( ny >= pTableLines->Count() ){ // Notbremse
1404 ASSERT( FALSE, "SwFltOutDoc:GetBox:ny >= Count()");
1405 ny = pTableLines->Count() - 1;
1407 SwTableLine* pTableLine = (*pTableLines)[ny];
1408 if(!pTableLine){
1409 ASSERT(FALSE, "SwFltOutDoc:GetBox:pTableLine");
1410 return 0;
1412 SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes();
1413 if(!pTableBoxes){
1414 ASSERT(FALSE, "SwFltOutDoc:GetBox:pTableBoxes");
1415 return 0;
1417 if( nx >= pTableBoxes->Count() ){ // Notbremse
1418 ASSERT(FALSE, "SwFltOutDoc:GetBox:nx >= Count()");
1419 nx = pTableBoxes->Count() - 1;
1421 SwTableBox* pTableBox = (*pTableBoxes)[nx];
1423 ASSERT(pTableBox != 0, "SwFltOutDoc:GetBox:pTableBox");
1424 return pTableBox;
1427 void SwFltOutDoc::NextTableCell()
1429 if(!pTable){
1430 ASSERT(pTable, "NextTableCell ohne Tabelle");
1431 return;
1433 const SwTableLines* pTableLines = &pTable->GetTabLines();
1434 SwTableLine* pTableLine = (*pTableLines)[usTableY];
1435 SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes();
1436 SwTableBox* pTableBox = (*pTableBoxes)[usTableX];
1437 ASSERT(pTableBox != 0, "SwFltOutDoc:NextTableCell:pTableBox");
1438 if(!pTableBox)
1439 return;
1440 //#pragma message(__FILE__ "(?) : Sw's const problem")
1441 // insert cells:
1442 if (++usTableX >= pTableBoxes->Count())
1443 GetDoc().GetNodes().InsBoxen(
1444 GetDoc().IsIdxInTbl(pPaM->GetPoint()->nNode),
1445 pTableLine,
1446 (SwTableBoxFmt*)pTableBox->GetFrmFmt(),
1447 GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ),
1449 pTableBoxes->Count());
1450 SeekCell(usTableY, usTableX, TRUE);
1451 pTableBox = (*pTableBoxes)[usTableX];
1452 ASSERT(pTableBox != 0, "SwFltOutDoc:pTableBox");
1453 if(pTableBox)
1454 (*pTableBoxes)[usTableX]->ClaimFrmFmt();
1457 void SwFltOutDoc::NextTableRow()
1459 SwTableBox* pTableBox = GetBox(usTableY, 0);
1460 if (pTableBox)
1462 // duplicate row:
1463 SwSelBoxes aSelBoxes;
1464 aSelBoxes.Insert( pTableBox );
1465 GetDoc().InsertRow(aSelBoxes);
1466 usTableX = 0;
1467 SeekCell(++usTableY, usTableX, TRUE);
1468 GetDoc().SetTxtFmtColl(*pPaM,
1469 GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ));
1473 void SwFltOutDoc::SetTableWidth(SwTwips nSwWidth)
1475 if(!pTable){
1476 ASSERT(pTable, "SetTableWidth ohne Tabelle");
1477 return;
1479 ASSERT( nSwWidth > MINLAY, "Tabellenbreite <= MINLAY" );
1480 if( nSwWidth != nTableWidth ){
1481 if( nTableWidth ) // Nicht beim ersten Setzen
1482 SplitTable();
1483 pTable->GetFrmFmt()->SetFmtAttr( SwFmtFrmSize(ATT_VAR_SIZE, nSwWidth));
1484 nTableWidth = nSwWidth;
1488 void SwFltOutDoc::SetTableOrient(sal_Int16 eOri)
1490 if(!pTable){
1491 ASSERT(pTable, "SetTableOrient ohne Tabelle");
1492 return;
1494 pTable->GetFrmFmt()->SetFmtAttr( SwFmtHoriOrient( 0, eOri ));
1497 void SwFltOutDoc::SetCellWidth(SwTwips nWidth, USHORT nCell /* = USHRT_MAX */ )
1499 if(!pTable){
1500 ASSERT(pTable, "SetCellWidth ohne Tabelle");
1501 return;
1503 ASSERT( nWidth > MINLAY, "Tabellenzellenbreite <= MINLAY" );
1504 if (nWidth < MINLAY)
1505 nWidth = MINLAY;
1507 SwTableBox* pTableBox = GetBox(usTableY, nCell);
1508 if(pTableBox && pTableBox->GetFrmFmt() ){
1509 SwFmtFrmSize aFmtFrmSize(ATT_FIX_SIZE);
1510 aFmtFrmSize.SetWidth(nWidth);
1511 pTableBox->GetFrmFmt()->SetFmtAttr(aFmtFrmSize);
1515 void SwFltOutDoc::SetCellHeight(SwTwips nHeight)
1517 if(!pTable){
1518 ASSERT(pTable, "SetCellHeight ohne Tabelle");
1519 return;
1522 const SwTableLines* pTableLines = &pTable->GetTabLines();
1523 SwTableLine* pTableLine = (*pTableLines)[usTableY];
1524 SwFmtFrmSize aFmtFrmSize(ATT_MIN_SIZE, 0, 0);
1525 if (nHeight < MINLAY)
1526 nHeight = MINLAY;
1527 aFmtFrmSize.SetHeight(nHeight);
1528 pTableLine->GetFrmFmt()->SetFmtAttr(aFmtFrmSize);
1531 const SfxPoolItem& SwFltOutDoc::GetCellAttr(USHORT nWhich)
1533 if (!pTable){
1534 ASSERT(pTable, "GetCellAttr ohne Table");
1535 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1538 SwTableBox* pTableBox = GetBox(usTableY, usTableX);
1539 if(!pTableBox)
1540 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1541 return pTableBox->GetFrmFmt()->GetFmtAttr( nWhich );
1544 void SwFltOutDoc::SetCellBorder(const SvxBoxItem& rFmtBox,
1545 USHORT nCell /* = USHRT_MAX */ )
1547 SwTableBox* pTableBox = GetBox(usTableY, nCell);
1548 if(pTableBox)
1549 pTableBox->GetFrmFmt()->SetFmtAttr(rFmtBox);
1552 // nicht aktiviert !!!
1553 void SwFltOutDoc::SetCellSpace(USHORT nDist)
1555 if(!pTable){
1556 ASSERT(pTable, "SetCellSpace ohne Tabelle");
1557 return;
1559 SwTableBox* pTableBox = GetBox(usTableY, usTableX);
1560 if(!pTableBox)
1561 return;
1563 SvxBoxItem aFmtBox( *((SvxBoxItem*)
1564 &pTableBox->GetFrmFmt()->GetFmtAttr( RES_BOX )));
1566 // versteh ich nich, sven: if (!nDist) nDist = 18; // ca. 0.03 cm
1567 if (nDist > 42) // max. 0.7 mm
1568 nDist = 42;
1569 else
1570 if (nDist < MIN_BORDER_DIST)
1571 nDist = MIN_BORDER_DIST;
1572 aFmtBox.SetDistance(nDist);
1573 pTableBox->GetFrmFmt()->SetFmtAttr(aFmtBox);
1576 void SwFltOutDoc::DeleteCell(USHORT nCell /* = USHRT_MAX */)
1578 SwTableBox* pTableBox = GetBox(usTableY, nCell);
1579 if(pTableBox){
1580 SwSelBoxes aSelBoxes;
1581 aSelBoxes.Insert( pTableBox );
1582 GetDoc().DeleteRowCol(aSelBoxes);
1583 usTableX--;
1587 void SwFltOutDoc::SplitTable()
1589 if(!pTable)
1591 ASSERT(pTable, "SplitTable ohne Tabelle");
1592 return;
1594 SwTableBox* pAktBox = GetBox(usTableY, usTableX);
1595 SwTableBox* pSplitBox = GetBox(usTableY - 1, 0);
1596 GetDoc().GetNodes().SplitTable(SwNodeIndex(*pSplitBox->GetSttNd()), false);
1597 pTable = &pAktBox->GetSttNd()->FindTableNode()->GetTable();
1598 usTableY = 0;
1601 void SwFltOutDoc::EndTable()
1603 if (!pTable){
1604 ASSERT(pTable, "EndTable ohne Table");
1605 return;
1607 // Alle Attribute schliessen, da sonst Attribute
1608 // entstehen koennen, die in Flys reinragen
1609 rStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1610 rEndStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1612 if (GetDoc().GetRootFrm()){
1613 SwTableNode* pTableNode = GetDoc().IsIdxInTbl(
1614 pPaM->GetPoint()->nNode);
1615 pTableNode->DelFrms();
1616 pTableNode->MakeFrms(&pPaM->GetPoint()->nNode);
1619 *pPaM->GetPoint() = *pTabSavedPos; // restore Cursor
1620 delete pTabSavedPos;
1621 pTabSavedPos = 0;
1622 ((SwTable*)pTable)->UnlockModify(); // Test, nuetzt nichts gegen Assert
1623 pTable = 0;
1624 nTableWidth = 0;
1627 BOOL SwFltOutDoc::SeekCell(short nRow, short nCol, BOOL bPam)
1629 // get structs to table cells
1630 const SwTableLines* pTableLines = &pTable->GetTabLines();
1631 SwTableLine* pTableLine = (*pTableLines)[usTableY];
1632 SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes();
1633 SwTableBox* pTableBox = (*pTableBoxes)[usTableX];
1635 if ((USHORT)nRow >= pTableLines->Count())
1637 ASSERT((USHORT)nRow >= pTableLines->Count(), "SwFltOutDoc");
1638 return FALSE;
1640 pTableLine = (*pTableLines)[nRow];
1641 pTableBoxes = &pTableLine->GetTabBoxes();
1642 if (nCol >= pTableBoxes->Count())
1643 return FALSE;
1644 pTableBox = (*pTableBoxes)[nCol];
1645 if( !pTableBox->GetSttNd() )
1647 ASSERT(pTableBox->GetSttNd(), "SwFltOutDoc");
1648 return FALSE;
1650 if(bPam)
1652 pPaM->GetPoint()->nNode = pTableBox->GetSttIdx() + 1;
1653 pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
1654 //#pragma message(__FILE__ "(?) : Sw's const problem")
1655 #if OSL_DEBUG_LEVEL > 1
1656 const SwTxtFmtColl* p = GetDoc().GetDfltTxtFmtColl();
1657 p = GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false );
1658 #endif
1659 GetDoc().SetTxtFmtColl(*pPaM,
1660 GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ));
1662 return TRUE;
1666 //-----------------------------------------------------------------------------
1667 // Flys in SwFltOutBase
1668 //-----------------------------------------------------------------------------
1670 SfxItemSet* SwFltOutBase::NewFlyDefaults()
1672 // Unbedingt noetige Standardwerte setzen ( falls diese Werte nicht
1673 // spaeter explizit gesetzt werden )
1675 SfxItemSet* p = new SfxItemSet( GetDoc().GetAttrPool(),
1676 RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
1677 SwFmtFrmSize aSz( ATT_VAR_SIZE, MINFLY, MINFLY );
1678 // Default: Breite 100% ( = PMW:Auto )
1679 aSz.SetWidthPercent( 100 ); // Hoehe: Auto
1680 p->Put( aSz );
1681 p->Put( SwFmtHoriOrient( 0, text::HoriOrientation::NONE, text::RelOrientation::FRAME ));
1682 return p;
1685 BOOL SwFltOutBase::BeginFly( RndStdIds eAnchor /*= FLY_AT_CNTNT*/,
1686 BOOL bAbsolutePos /*= FALSE*/,
1687 const SfxItemSet*
1688 #ifndef PRODUCT
1689 pMoreAttrs /*= 0*/
1690 #endif
1693 ASSERT(!pMoreAttrs, "SwFltOutBase:BeginFly mit pMoreAttrs" );
1694 eFlyAnchor = eAnchor;
1695 bFlyAbsPos = bAbsolutePos; // Bloedsinn eigentlich
1696 return TRUE;
1699 /*virtual*/ void SwFltOutBase::SetFlyAnchor( RndStdIds eAnchor )
1701 if( !IsInFly() ){
1702 ASSERT( FALSE, "SetFlyAnchor() ohne Fly" );
1703 return;
1705 if( eAnchor == FLY_IN_CNTNT ){
1706 ASSERT( FALSE, "SetFlyAnchor( FLY_IN_CNTNT ) nicht implementiert" );
1707 return;
1709 SwFmtAnchor& rAnchor = (SwFmtAnchor&)GetFlyFrmAttr( RES_ANCHOR );
1710 rAnchor.SetType( eAnchor );
1713 void SwFltOutBase::EndFly()
1715 if( bFlyAbsPos ){
1716 // hier muessen die absoluten Positionen am Fly noch in
1717 // die Writer-Koordinaten umgerechnet werden.
1721 //-----------------------------------------------------------------------------
1722 // Flys in SwFltDoc
1723 //-----------------------------------------------------------------------------
1725 /* virtual */ BOOL SwFltOutDoc::IsInFly()
1727 return pFly != 0;
1730 SwFrmFmt* SwFltOutDoc::MakeFly( RndStdIds eAnchor, SfxItemSet* pSet )
1732 pFly = (SwFlyFrmFmt*)GetDoc().MakeFlySection( eAnchor, pPaM->GetPoint(),
1733 pSet );
1734 return pFly;
1737 BOOL SwFltOutDoc::BeginFly( RndStdIds eAnchor /*= FLY_AT_CNTNT*/,
1738 BOOL bAbsolutePos /*= FALSE*/,
1739 const SfxItemSet* pMoreAttrs /*= 0*/ )
1742 SwFltOutBase::BeginFly( eAnchor, bAbsolutePos, 0 );
1743 SfxItemSet* pSet = NewFlyDefaults();
1745 // Alle Attribute schliessen, da sonst Attribute entstehen koennen,
1746 // die in Flys reinragen
1747 rStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1748 rEndStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1750 // create Fly:
1751 ASSERT(pFlySavedPos == NULL, "BeginFly in Fly"); // rekursiv geht noch nicht
1752 pFlySavedPos = new SwPosition(*pPaM->GetPoint());
1755 SwFmtAnchor aAnchor( eAnchor, 1 );
1757 // Wenn Fly-Attribute im Style waren, dann jetzt als Defaults reinsetzen
1758 if (pMoreAttrs)
1759 pSet->Put(*pMoreAttrs);
1761 // dieses NICHT bei Seitengebundenem Fly mit Seiten-NUMMER !
1762 aAnchor.SetAnchor(pPaM->GetPoint()); // braucht erstaunlicherweise
1763 // den Stack nicht
1764 // aStack.NewAttr( *pPaM->GetPoint(), SwFltAnchor( pFly ) );
1766 pSet->Put( aAnchor );
1767 SwFrmFmt* pF = MakeFly( eAnchor, pSet );
1768 delete pSet;
1770 // set pam in Fly
1771 const SwFmtCntnt& rCntnt = pF->GetCntnt();
1772 ASSERT( rCntnt.GetCntntIdx(), "Kein Inhalt vorbereitet." );
1773 pPaM->GetPoint()->nNode = rCntnt.GetCntntIdx()->GetIndex() + 1;
1774 SwCntntNode *pNode = pPaM->GetCntntNode();
1775 pPaM->GetPoint()->nContent.Assign( pNode, 0 );
1777 return TRUE;
1780 /*virtual*/ void SwFltOutDoc::SetFlyFrmAttr(const SfxPoolItem& rAttr)
1782 if (pFly){
1783 pFly->SetFmtAttr( rAttr );
1784 }else{
1785 ASSERT(pFly, "SetFlyAttr ohne Doc-Fly");
1786 return;
1790 /*virtual*/ const SfxPoolItem& SwFltOutDoc::GetFlyFrmAttr(USHORT nWhich)
1792 if (pFly){
1793 return pFly->GetFmtAttr( nWhich );
1794 }else{
1795 ASSERT(pFly, "GetFlyAttr ohne Fly");
1796 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1800 void SwFltOutDoc::EndFly()
1802 if( pTable ){
1803 ASSERT( FALSE, "SwFltOutDoc::EndFly() in Table" );
1804 return;
1806 // Alle Attribute schliessen, da sonst Attribute
1807 // entstehen koennen, die aus Flys rausragen
1808 rStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1809 rEndStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1811 *pPaM->GetPoint() = *pFlySavedPos; // restore Cursor
1812 delete pFlySavedPos;
1813 pFlySavedPos = 0;
1814 SwFltOutBase::EndFly();
1815 pFly = 0;
1818 //-----------------------------------------------------------------------------
1819 // Flys in SwFltFormatCollection
1820 //-----------------------------------------------------------------------------
1821 /*virtual*/ BOOL SwFltFormatCollection::IsInFly()
1823 return bHasFly;
1826 /*virtual*/ void SwFltFormatCollection::SetFlyFrmAttr(const SfxPoolItem& rAttr)
1828 if (!pFlyAttrs)
1829 pFlyAttrs = new SfxItemSet( GetDoc().GetAttrPool(),
1830 RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
1831 pFlyAttrs->Put( rAttr );
1834 /*virtual*/ const SfxPoolItem& SwFltFormatCollection::GetFlyFrmAttr(USHORT nWhich)
1836 // ASSERT( pFlyAttrs, "GetFlyFrmAttr ohne Coll-FlyAttrs" );
1837 if( pFlyAttrs )
1838 return pFlyAttrs->Get( nWhich, FALSE );
1839 else
1840 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1843 BOOL SwFltFormatCollection::BeginFly( RndStdIds eAnchor /*= FLY_AT_CNTNT*/,
1844 BOOL bAbsolutePos /*= FALSE*/,
1845 const SfxItemSet* pMoreAttrs /*= 0*/ )
1848 SwFltOutBase::BeginFly( eAnchor, bAbsolutePos, pMoreAttrs );
1849 bHasFly = TRUE;
1850 return TRUE;
1853 void SwFltFormatCollection::EndFly() // Wird nie aufgerufen
1857 BOOL SwFltFormatCollection::BeginStyleFly( SwFltOutDoc* pOutDoc )
1859 ASSERT( pOutDoc, "BeginStyleFly ohne pOutDoc" );
1860 ASSERT( pOutDoc && !pOutDoc->IsInFly(), "BeginStyleFly in Fly" );
1861 if( pOutDoc && !pOutDoc->IsInFly() )
1862 return pOutDoc->BeginFly( eFlyAnchor, bFlyAbsPos, pFlyAttrs );
1863 else
1864 return FALSE;
1867 //-----------------------------------------------------------------------------
1868 // Flys in SwFltShell
1869 //-----------------------------------------------------------------------------
1871 BOOL SwFltShell::BeginFly( RndStdIds eAnchor /*= FLY_AT_CNTNT*/,
1872 BOOL bAbsolutePos /*= FALSE*/ )
1875 if (pOut->IsInFly()){
1876 ASSERT(FALSE, "BeginFly in Fly");
1877 return FALSE;
1879 if (pOutDoc->IsInTable()){
1880 ASSERT(FALSE, "BeginFly in Table");
1881 return FALSE;
1883 pOut->BeginFly( eAnchor, bAbsolutePos, pColls[nAktStyle]->GetpFlyAttrs() );
1884 eSubMode = Fly;
1885 return TRUE;
1888 void SwFltShell::SetFlyXPos( short nXPos, sal_Int16 eHRel /*= text::RelOrientation::FRAME*/,
1889 sal_Int16 eHAlign /*= text::HoriOrientation::NONE*/ )
1891 SetFlyFrmAttr( SwFmtHoriOrient( nXPos, eHAlign, eHRel ) );
1894 void SwFltShell::SetFlyYPos( short nYPos, sal_Int16 eVRel /*= text::RelOrientation::FRAME*/,
1895 sal_Int16 eVAlign /*= text::VertOrientation::NONE*/ )
1897 SetFlyFrmAttr( SwFmtVertOrient( nYPos, eVAlign, eVRel ) );
1901 void SwFltShell::EndFly()
1903 if (!pOut->IsInFly()){
1904 ASSERT(FALSE, "EndFly ohne Fly");
1905 return;
1907 if (pOutDoc->IsInTable()){ // Table verschraenkt mit Fly macht keinen Sinn
1908 ASSERT(FALSE, "EndFly in Table ( verschraenkt )");
1909 EndTable(); // -> Table beenden
1911 pOut->EndFly();
1912 eSubMode = None;
1915 //-----------------------------------------------------------------------------
1916 // Fussnoten
1917 //-----------------------------------------------------------------------------
1919 void SwFltShell::BeginFootnote()
1921 if( pOut->IsInFly() ){ // Passiert z.B. bei Fussnote in Fly
1922 ASSERT(FALSE, "Fussnote in Fly nicht erlaubt");
1923 return;
1925 if( pOutDoc->IsInTable() ){
1926 ASSERT(FALSE, "Fussnote in Table z.Zt. nicht erlaubt");
1927 return;
1930 // Alle Attribute schliessen, da sonst Attribute entstehen koennen,
1931 // die in Fussnoten reinragen
1932 aStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1933 // aEndStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1934 // EndStack erstmal nicht zwangs-Schliessen, damit Bookmarks ueber
1935 // Fussnoten im PMW uebernommen werden
1937 SwFmtFtn aFtn;
1938 GetDoc().InsertPoolItem(*pPaM, aFtn, 0);
1939 ASSERT(pSavedPos == NULL, "SwFltShell");
1940 pSavedPos = new SwPosition(*pPaM->GetPoint());
1941 pPaM->Move(fnMoveBackward, fnGoCntnt);
1942 SwTxtNode* pTxt = pPaM->GetNode()->GetTxtNode();
1943 SwTxtAttr* pFN = pTxt->GetTxtAttr(pPaM->GetPoint()->nContent,
1944 RES_TXTATR_FTN);
1945 if( !pFN ){ // Passiert z.B. bei Fussnote in Fly
1946 ASSERT(pFN, "Probleme beim Anlegen des Fussnoten-Textes");
1947 return;
1949 const SwNodeIndex* pStartIndex = ((SwTxtFtn*)pFN)->GetStartNode();
1950 ASSERT(pStartIndex, "Probleme beim Anlegen des Fussnoten-Textes");
1951 pPaM->GetPoint()->nNode = pStartIndex->GetIndex() + 1;
1952 pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
1953 eSubMode = Footnote;
1956 void SwFltShell::EndFootnote()
1958 if(!pSavedPos)
1959 return;
1960 // Alle Attribute schliessen, da sonst Attribute
1961 // entstehen koennen, die aus Fussnoten rausragen
1962 aStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1963 // aEndStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1964 // EndStack erstmal nicht zwangs-Schliessen, damit Bookmarks ueber
1965 // Fussnoten im PMW uebernommen werden
1967 *pPaM->GetPoint() = *pSavedPos; // restore Cursor
1968 delete pSavedPos;
1969 pSavedPos = 0;
1972 void SwFltShell::BeginHeader(SwPageDesc* /*pPD*/)
1974 SwFrmFmt* pFmt = &pCurrentPageDesc->GetMaster(
1975 ); //(bUseLeft) ? &pCurrentPageDesc->GetLeft() :
1976 SwFrmFmt* pHdFtFmt;
1977 pFmt->SetFmtAttr(SwFmtHeader(TRUE));
1978 pHdFtFmt = (SwFrmFmt*)pFmt->GetHeader().GetHeaderFmt();
1979 const SwNodeIndex* pStartIndex = pHdFtFmt->GetCntnt().GetCntntIdx();
1980 if (!pStartIndex)
1981 return;
1982 ASSERT(pSavedPos == NULL, "SwFltShell");
1983 pSavedPos = new SwPosition(*pPaM->GetPoint());
1984 pPaM->GetPoint()->nNode = pStartIndex->GetIndex() + 1;
1985 pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
1986 eSubMode = Header;
1989 void SwFltShell::BeginFooter(SwPageDesc* /*pPD*/)
1991 SwFrmFmt* pFmt = &pCurrentPageDesc->GetMaster(
1992 ); //(bUseLeft) ? &pCurrentPageDesc->GetLeft() :
1993 SwFrmFmt* pHdFtFmt;
1994 pFmt->SetFmtAttr(SwFmtFooter(TRUE));
1995 pHdFtFmt = (SwFrmFmt*)pFmt->GetFooter().GetFooterFmt();
1996 const SwNodeIndex* pStartIndex = pHdFtFmt->GetCntnt().GetCntntIdx();
1997 if (!pStartIndex)
1998 return;
1999 ASSERT(pSavedPos == NULL, "SwFltShell");
2000 pSavedPos = new SwPosition(*pPaM->GetPoint());
2001 pPaM->GetPoint()->nNode = pStartIndex->GetIndex() + 1;
2002 pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
2003 eSubMode = Footer;
2006 void SwFltShell::EndHeaderFooter()
2008 *pPaM->GetPoint() = *pSavedPos; // restore Cursor
2009 delete pSavedPos;
2010 pSavedPos = 0;
2013 SwPageDesc* SwFltShell::MakePageDesc(SwPageDesc* pFirstPageDesc)
2015 if(bStdPD) // keine Neuen PageDescs
2016 return pCurrentPageDesc;
2018 BOOL bFollow = (pFirstPageDesc != 0);
2019 SwPageDesc* pNewPD;
2020 USHORT nPos;
2021 if (bFollow && pFirstPageDesc->GetFollow() != pFirstPageDesc)
2022 return pFirstPageDesc; // Fehler: hat schon Follow
2023 // Erkennung doppelter Namen fehlt noch (Wahrscheinlichkeit
2024 // fuer dopp. Namen ist gering)
2026 nPos = GetDoc().MakePageDesc( ViewShell::GetShellRes()->GetPageDescName(
2027 GetDoc().GetPageDescCnt(), FALSE, bFollow ),
2028 pFirstPageDesc, FALSE );
2030 pNewPD = &((SwPageDesc&)const_cast<const SwDoc &>(GetDoc()).
2031 GetPageDesc(nPos));
2032 if (bFollow)
2033 { // Dieser ist der folgende von pPageDesc
2034 pFirstPageDesc->SetFollow(pNewPD);
2035 pNewPD->SetFollow(pNewPD);
2037 else
2039 GetDoc().InsertPoolItem( *pPaM, SwFmtPageDesc( pNewPD ), 0 );
2041 pNewPD->WriteUseOn( // alle Seiten
2042 (UseOnPage)(nsUseOnPage::PD_ALL | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE));
2043 return pNewPD;
2046 ///////////////////////////////////////////////// SwFltFormatCollection
2047 SwFltFormatCollection::SwFltFormatCollection(
2048 SwDoc& _rDoc, RES_POOL_COLLFMT_TYPE nType ) :
2049 SwFltOutBase(_rDoc),
2050 pColl(_rDoc.GetTxtCollFromPool( static_cast< sal_uInt16 >(nType), false )),
2051 pFlyAttrs( 0 ),
2052 bHasFly( FALSE )
2054 Reset(); // Default-Attrs loeschen und Auto-Flag
2057 SwFltFormatCollection::SwFltFormatCollection(
2058 SwDoc& _rDoc, const String& rName ) :
2059 SwFltOutBase(_rDoc),
2060 pFlyAttrs( 0 ),
2061 bHasFly( FALSE )
2063 pColl = _rDoc.MakeTxtFmtColl(rName, (SwTxtFmtColl*)_rDoc.GetDfltTxtFmtColl());
2064 Reset(); // Default-Attrs loeschen und Auto-Flag
2067 void SwFltShell::NextStyle(USHORT nWhich, USHORT nNext)
2069 ASSERT(pColls[nWhich], "Next style for noexistent style" );
2070 ASSERT(pColls[nNext], "Next style to noexistent style" );
2071 if( pColls[nWhich] && pColls[nNext] )
2072 pColls[nWhich]->GetColl()->SetNextTxtFmtColl(
2073 *pColls[nNext]->GetColl() );
2076 // UpdatePageDescs muss am Ende des Einlesevorganges aufgerufen werden, damit
2077 // der Writer den Inhalt der Pagedescs wirklich akzeptiert
2078 void UpdatePageDescs(SwDoc &rDoc, sal_uInt16 nInPageDescOffset)
2080 // Pagedescriptoren am Dokument updaten (nur so werden auch die
2081 // linken Seiten usw. eingestellt).
2083 // PageDesc "Standard"
2084 rDoc.ChgPageDesc(0, const_cast<const SwDoc &>(rDoc).GetPageDesc(0));
2086 // PageDescs "Konvert..."
2087 for (sal_uInt16 i = nInPageDescOffset; i < rDoc.GetPageDescCnt(); ++i)
2088 rDoc.ChgPageDesc(i, const_cast<const SwDoc &>(rDoc).GetPageDesc(i));
2091 /* vi:set tabstop=4 shiftwidth=4 expandtab: */