update dev300-m58
[ooovba.git] / sw / source / filter / ww1 / fltshell.cxx
blob516efdb7879f76d0976f3fe9fb7595ac1011bcba
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->Insert(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->Insert(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->Insert(aRegion, *((SwFltSection*)pEntry->pAttr)->GetSection(),
568 0, FALSE);
569 delete(((SwFltSection*)pEntry->pAttr)->GetSection());
570 break;
571 case RES_FLTR_REDLINE:
573 if (pEntry->MakeRegion(pDoc, aRegion, TRUE))
575 pDoc->SetRedlineMode((RedlineMode_t)( nsRedlineMode_t::REDLINE_ON
576 | nsRedlineMode_t::REDLINE_SHOW_INSERT
577 | nsRedlineMode_t::REDLINE_SHOW_DELETE ));
578 SwFltRedline& rFltRedline = *((SwFltRedline*)pEntry->pAttr);
580 if( USHRT_MAX != rFltRedline.nAutorNoPrev )
582 SwRedlineData aData(rFltRedline.eTypePrev,
583 rFltRedline.nAutorNoPrev,
584 rFltRedline.aStampPrev,
585 aEmptyStr,
588 pDoc->AppendRedline(new SwRedline(aData, aRegion), true);
590 SwRedlineData aData(rFltRedline.eType,
591 rFltRedline.nAutorNo,
592 rFltRedline.aStamp,
593 aEmptyStr,
596 pDoc->AppendRedline( new SwRedline(aData, aRegion), true );
597 pDoc->SetRedlineMode((RedlineMode_t)( nsRedlineMode_t::REDLINE_NONE
598 | nsRedlineMode_t::REDLINE_SHOW_INSERT
599 | nsRedlineMode_t::REDLINE_SHOW_DELETE ));
602 break;
603 default:
604 if (pEntry->MakeRegion(pDoc, aRegion, FALSE))
605 pDoc->Insert(aRegion, *pEntry->pAttr, 0);
606 break;
610 SfxPoolItem* SwFltControlStack::GetFmtStackAttr(USHORT nWhich, USHORT * pPos)
612 SwFltStackEntry* pEntry;
613 USHORT nSize = static_cast< USHORT >(Count());
615 while (nSize)
617 // ist es das gesuchte Attribut ? (gueltig sind nur gelockte,
618 // also akt. gesetzte Attribute!!)
619 if ((pEntry = (*this)[ --nSize ])->bLocked &&
620 pEntry->pAttr->Which() == nWhich)
622 if (pPos)
623 *pPos = nSize;
624 return (SfxPoolItem*)pEntry->pAttr; // Ok, dann Ende
627 return 0;
630 const SfxPoolItem* SwFltControlStack::GetFmtAttr(const SwPosition& rPos, USHORT nWhich)
632 SfxPoolItem* pHt = GetFmtStackAttr(nWhich);
633 if (pHt)
634 return (const SfxPoolItem*)pHt;
636 // im Stack ist das Attribut nicht vorhanden, also befrage das Dokument
637 // SwCntntNode * pNd = rPaM.GetCntntNode();
638 SwCntntNode * pNd = pDoc->GetNodes()[ rPos.nNode ]->GetCntntNode();
640 if (!pNd) // kein ContentNode, dann das dflt. Attribut
641 return &pDoc->GetAttrPool().GetDefaultItem(nWhich);
642 return &pNd->GetAttr(nWhich);
645 void SwFltControlStack::Delete(const SwPaM &rPam)
647 const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
649 if( !rPam.HasMark() || *pStt >= *pEnd )
650 return;
652 SwNodeIndex aStartNode(pStt->nNode, -1);
653 USHORT nStartIdx = pStt->nContent.GetIndex();
654 SwNodeIndex aEndNode(pEnd->nNode, -1);
655 USHORT nEndIdx = pEnd->nContent.GetIndex();
657 //We don't support deleting content that is over one node, or removing a node.
658 ASSERT(aEndNode == aStartNode, "nodes must be the same, or this method extended");
659 if (aEndNode != aStartNode)
660 return;
662 for (USHORT nSize = static_cast< USHORT >(Count()); nSize > 0;)
664 SwFltStackEntry* pEntry = (*this)[--nSize];
666 bool bEntryStartAfterSelStart =
667 (pEntry->nMkNode == aStartNode && pEntry->nMkCntnt >= nStartIdx);
669 bool bEntryStartBeforeSelEnd =
670 (pEntry->nMkNode == aEndNode && pEntry->nMkCntnt <= nEndIdx);
672 bool bEntryEndAfterSelStart = false;
673 bool bEntryEndBeforeSelEnd = false;
674 if (!pEntry->bLocked)
676 bEntryEndAfterSelStart =
677 (pEntry->nPtNode == aStartNode && pEntry->nPtCntnt >= nStartIdx);
679 bEntryEndBeforeSelEnd =
680 (pEntry->nPtNode == aEndNode && pEntry->nPtCntnt <= nEndIdx);
683 bool bTotallyContained = false;
684 if (
685 bEntryStartAfterSelStart && bEntryStartBeforeSelEnd &&
686 bEntryEndAfterSelStart && bEntryEndBeforeSelEnd
689 bTotallyContained = true;
692 if (bTotallyContained)
694 //after start, before end, delete
695 DeleteAndDestroy(nSize);
696 continue;
699 xub_StrLen nCntntDiff = nEndIdx - nStartIdx;
701 //to be adjusted
702 if (bEntryStartAfterSelStart)
704 if (bEntryStartBeforeSelEnd)
706 //move start to new start
707 pEntry->nMkNode = aStartNode;
708 pEntry->nMkCntnt = nStartIdx;
710 else
711 pEntry->nMkCntnt = pEntry->nMkCntnt - nCntntDiff;
714 if (bEntryEndAfterSelStart)
716 if (bEntryEndBeforeSelEnd)
718 pEntry->nPtNode = aStartNode;
719 pEntry->nPtCntnt = nStartIdx;
721 else
722 pEntry->nPtCntnt = pEntry->nPtCntnt - nCntntDiff;
725 //That's what locked is, end equal to start, and nPtCntnt is invalid
726 if (pEntry->bLocked)
727 pEntry->nPtNode = pEntry->nMkNode;
731 //------ hier stehen die Methoden von SwFltAnchor -----------
732 SwFltAnchor::SwFltAnchor(SwFrmFmt* pFmt) :
733 SfxPoolItem(RES_FLTR_ANCHOR), pFrmFmt(pFmt)
735 pClient = new SwFltAnchorClient(this);
736 pFrmFmt->Add(pClient);
739 SwFltAnchor::SwFltAnchor(const SwFltAnchor& rCpy) :
740 SfxPoolItem(RES_FLTR_ANCHOR), pFrmFmt(rCpy.pFrmFmt)
742 pClient = new SwFltAnchorClient(this);
743 pFrmFmt->Add(pClient);
746 SwFltAnchor::~SwFltAnchor()
748 delete pClient;
751 void SwFltAnchor::SetFrmFmt(SwFrmFmt * _pFrmFmt)
753 pFrmFmt = _pFrmFmt;
756 const SwFrmFmt * SwFltAnchor::GetFrmFmt() const
758 return pFrmFmt;
761 SwFrmFmt * SwFltAnchor::GetFrmFmt()
763 return pFrmFmt;
766 int SwFltAnchor::operator==(const SfxPoolItem& rItem) const
768 return pFrmFmt == ((SwFltAnchor&)rItem).pFrmFmt;
771 SfxPoolItem* __EXPORT SwFltAnchor::Clone(SfxItemPool*) const
773 return new SwFltAnchor(*this);
776 // SwFltAnchorClient
778 SwFltAnchorClient::SwFltAnchorClient(SwFltAnchor * pFltAnchor)
779 : m_pFltAnchor(pFltAnchor)
783 void SwFltAnchorClient::Modify(SfxPoolItem *, SfxPoolItem * pNew)
785 if (pNew->Which() == RES_FMT_CHG)
787 SwFmtChg * pFmtChg = dynamic_cast<SwFmtChg *> (pNew);
789 if (pFmtChg != NULL)
791 SwFrmFmt * pFrmFmt = dynamic_cast<SwFrmFmt *> (pFmtChg->pChangedFmt);
793 if (pFrmFmt != NULL)
794 m_pFltAnchor->SetFrmFmt(pFrmFmt);
799 //------ hier stehen die Methoden von SwFltRedline -----------
800 int SwFltRedline::operator==(const SfxPoolItem& rItem) const
802 return this == &rItem;
805 SfxPoolItem* SwFltRedline::Clone( SfxItemPool* ) const
807 return new SwFltRedline(*this);
810 //------ hier stehen die Methoden von SwFltBookmark -----------
811 SwFltBookmark::SwFltBookmark( const String& rNa, const String& rVa,
812 long nHand, BOOL bOnlyR )
813 : SfxPoolItem(RES_FLTR_BOOKMARK), nHandle(nHand), aName(rNa), aVal(rVa),
814 bOnlyRef(bOnlyR), bRef(FALSE), bPgRef(FALSE)
816 // eSrc: CHARSET_DONTKNOW fuer keine UEbersetzung bei operator <<
817 // Upcase wird immer gemacht.
818 // bei XXXStack.NewAttr(...) wird nie eine UEbersetzung vorgenommen.
819 // ansonsten: uebergebener Src-Charset fuer aName
820 // im Filter eingestellter Src-Charset fuer aVal ( Text )
823 SwFltBookmark::SwFltBookmark(const SwFltBookmark& rCpy)
824 : SfxPoolItem(RES_FLTR_BOOKMARK),
825 nHandle(rCpy.nHandle),
826 aName(rCpy.aName),
827 aVal(rCpy.aVal),
828 bOnlyRef(rCpy.bOnlyRef),
829 bRef(rCpy.bRef),
830 bPgRef(rCpy.bPgRef)
834 int SwFltBookmark::operator==(const SfxPoolItem& rItem) const
836 return (aName == ((SwFltBookmark&)rItem).aName)
837 && (nHandle == ((SwFltBookmark&)rItem).nHandle);
840 SfxPoolItem* SwFltBookmark::Clone(SfxItemPool*) const
842 return new SwFltBookmark(*this);
845 //------ hier stehen die Methoden von SwFltTOX -----------
847 SwFltTOX::SwFltTOX(SwTOXBase* pBase, USHORT _nCols)
848 : SfxPoolItem(RES_FLTR_TOX), pTOXBase(pBase), nCols( _nCols ),
849 bHadBreakItem( FALSE ), bHadPageDescItem( FALSE )
853 SwFltTOX::SwFltTOX(const SwFltTOX& rCpy)
854 : SfxPoolItem(RES_FLTR_TOX), pTOXBase(rCpy.pTOXBase), nCols( rCpy.nCols ),
855 bHadBreakItem( rCpy.bHadBreakItem ), bHadPageDescItem( rCpy.bHadPageDescItem )
859 int SwFltTOX::operator==(const SfxPoolItem& rItem) const
861 return pTOXBase == ((SwFltTOX&)rItem).pTOXBase;
864 SfxPoolItem* SwFltTOX::Clone(SfxItemPool*) const
866 return new SwFltTOX(*this);
869 //------ hier stehen die Methoden von SwFltSwSection -----------
871 SwFltSection::SwFltSection(SwSection *pSect) :
872 SfxPoolItem(RES_FLTR_SECTION), pSection(pSect)
876 SwFltSection::SwFltSection(const SwFltSection& rCpy) :
877 SfxPoolItem(RES_FLTR_SECTION), pSection(rCpy.pSection)
881 int SwFltSection::operator==(const SfxPoolItem& rItem) const
883 return pSection == ((SwFltSection&)rItem).pSection;
886 SfxPoolItem* __EXPORT SwFltSection::Clone(SfxItemPool*) const
888 return new SwFltSection(*this);
891 ///////////////////////////////////////////////////////////////////////
893 // hier beginnt der von mdt erzeugte code. dieser ist eine shell auf
894 // der writer-seite nach moeglichkeit bald fuer alle filter. die ganze
895 // schwierigkeit, texte & formatattribute einzufuegen, die positionen
896 // zu verwalten, styles & kopf/fuszzeilen etc.
899 //////////////////////////////////////////////////////////// SwFltShell
900 SwFltShell::SwFltShell(SwDoc* pDoc, SwPaM& rPaM, const String& rBaseURL, BOOL bNew, ULONG nFieldFl) :
901 pCurrentPageDesc(0),
902 pSavedPos(0),
903 eSubMode(None),
904 nAktStyle(0),
905 aStack(pDoc, nFieldFl),
906 aEndStack(pDoc, nFieldFl),
907 pPaM(new SwPaM(*(rPaM.GetPoint()))),
908 sBaseURL(rBaseURL),
909 nPageDescOffset(GetDoc().GetPageDescCnt()),
910 eSrcCharSet(RTL_TEXTENCODING_MS_1252),
911 bNewDoc(bNew),
912 bStdPD(FALSE),
913 bProtect(FALSE)
915 memset( pColls, 0, sizeof( pColls ) );
916 pOutDoc = new SwFltOutDoc( *pDoc, pPaM, aStack, aEndStack );
917 pOut = pOutDoc;
919 if( !bNewDoc ){ // in ein Dokument einfuegen ?
920 // Da immer ganze Zeile eingelesen werden, muessen
921 // evtl. Zeilen eingefuegt / aufgebrochen werden
922 const SwPosition* pPos = pPaM->GetPoint();
923 const SwTxtNode* pSttNd = pPos->nNode.GetNode().GetTxtNode();
924 USHORT nCntPos = pPos->nContent.GetIndex();
925 if( nCntPos && pSttNd->GetTxt().Len() )
926 // EinfuegePos nicht in leerer Zeile
927 pDoc->SplitNode( *pPos, false ); // neue Zeile erzeugen
928 if( pSttNd->GetTxt().Len() ){ // EinfuegePos nicht am Ende der Zeile
929 pDoc->SplitNode( *pPos, false ); // neue Zeile
930 pPaM->Move( fnMoveBackward ); // gehe in leere Zeile
933 // verhinder das Einlesen von Tabellen in Fussnoten / Tabellen
934 ULONG nNd = pPos->nNode.GetIndex();
935 BOOL bReadNoTbl = 0 != pSttNd->FindTableNode() ||
936 ( nNd < pDoc->GetNodes().GetEndOfInserts().GetIndex() &&
937 pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() < nNd );
938 if( bReadNoTbl )
939 pOutDoc->SetReadNoTable();
941 pCurrentPageDesc = &((SwPageDesc&)const_cast<const SwDoc *>(pDoc)
942 ->GetPageDesc( 0 )); // Standard
946 SwFltShell::~SwFltShell()
948 USHORT i;
950 if (eSubMode == Style)
951 EndStyle();
952 if( pOutDoc->IsInTable() ) // falls nicht ordentlich abgeschlossen
953 EndTable();
954 if( pOutDoc->IsInFly() )
955 EndFly();
957 GetDoc().SetUpdateExpFldStat(true);
958 GetDoc().SetInitDBFields(TRUE);
959 aStack.SetAttr(*pPaM->GetPoint(), 0, FALSE);
960 aStack.SetAttr(*pPaM->GetPoint(), 0, FALSE);
961 aEndStack.SetAttr(*pPaM->GetPoint(), 0, FALSE);
962 aEndStack.SetAttr(*pPaM->GetPoint(), 0, FALSE);
963 if( bProtect ){ // Das ganze Doc soll geschuetzt sein
965 SwDoc& rDoc = GetDoc();
966 // 1. SectionFmt und Section anlegen
967 SwSectionFmt* pSFmt = rDoc.MakeSectionFmt( 0 );
968 SwSection aS( CONTENT_SECTION, String::CreateFromAscii(
969 RTL_CONSTASCII_STRINGPARAM("PMW-Protect") ));
970 aS.SetProtect( TRUE );
971 // 2. Start- und EndIdx suchen
972 const SwNode* pEndNd = &rDoc.GetNodes().GetEndOfContent();
973 SwNodeIndex aEndIdx( *pEndNd, -1L );
974 const SwStartNode* pSttNd = pEndNd->StartOfSectionNode();
975 SwNodeIndex aSttIdx( *pSttNd, 1L ); // +1 -> hinter StartNode
976 // Section einfuegen
977 // Section einfuegen
978 rDoc.GetNodes().InsertSection( aSttIdx, *pSFmt, aS, &aEndIdx, FALSE );
980 if( !IsFlagSet(SwFltControlStack::DONT_HARD_PROTECT) ){
981 SwDocShell* pDocSh = rDoc.GetDocShell();
982 if( pDocSh )
983 pDocSh->SetReadOnlyUI( TRUE );
986 // Pagedescriptoren am Dokument updaten (nur so werden auch die
987 // linken Seiten usw. eingestellt).
989 GetDoc().ChgPageDesc( 0,
990 const_cast<const SwDoc &>(GetDoc()).
991 GetPageDesc( 0 )); // PageDesc "Standard"
992 for (i=nPageDescOffset;i<GetDoc().GetPageDescCnt();i++)
994 const SwPageDesc& rPD = const_cast<const SwDoc &>(GetDoc()).
995 GetPageDesc(i);
996 GetDoc().ChgPageDesc(i, rPD);
999 delete pPaM;
1000 for (i=0; i<sizeof(pColls)/sizeof(*pColls); i++)
1001 if( pColls[i] )
1002 delete pColls[i];
1003 delete pOutDoc;
1006 SwFltShell& SwFltShell::operator << ( const String& rStr )
1008 ASSERT(eSubMode != Style, "char insert while in style-mode");
1009 GetDoc().Insert( *pPaM, rStr, true );
1010 return *this;
1013 void SwFltShell::ConvertUStr( String& rInOut )
1015 GetAppCharClass().toUpper( rInOut );
1018 // QuoteString() wandelt CRs abhaengig von nFieldIniFlags in '\n' oder "\0x0d"
1019 String SwFltShell::QuoteStr( const String& rIn )
1021 String sOut( rIn );
1022 BOOL bAllowCr = aStack.IsFlagSet( SwFltControlStack::ALLOW_FLD_CR );
1024 for( xub_StrLen n = 0; n < sOut.Len(); ++n )
1026 switch( sOut.GetChar( n ) )
1028 case 0x0a:
1029 sOut.Erase( n, 1 ); // 0xd 0xa wird zu \n
1030 break;
1032 case 0x0b:
1033 case 0x0c:
1034 case 0x0d:
1035 if( bAllowCr )
1036 sOut.SetChar( n, '\n' );
1037 break;
1040 return sOut;
1043 SwFltShell& SwFltShell::operator << ( const sal_Unicode c )
1045 ASSERT( eSubMode != Style, "char insert while in style-mode");
1046 GetDoc().Insert( *pPaM, c );
1047 return *this;
1050 SwFltShell& SwFltShell::AddError( const sal_Char* pErr )
1052 String aName( String::CreateFromAscii(
1053 RTL_CONSTASCII_STRINGPARAM( "ErrorTag" )));
1054 SwFieldType* pFT = GetDoc().GetFldType( RES_SETEXPFLD, aName, false );
1055 if( pFT == 0)
1057 SwSetExpFieldType aS(&GetDoc(), aName, nsSwGetSetExpType::GSE_STRING);
1058 pFT = GetDoc().InsertFldType(aS);
1060 SwSetExpField aFld( (SwSetExpFieldType*)pFT,
1061 String::CreateFromAscii( pErr ));
1062 //, VVF_INVISIBLE
1063 GetDoc().Insert(*pPaM, SwFmtFld(aFld), 0);
1064 return *this;
1067 SwFltShell& SwFltShell::operator << (Graphic& rGraphic)
1069 // embedded Grafik !!
1070 GetDoc().Insert(*pPaM, aEmptyStr, aEmptyStr, &rGraphic, NULL, NULL, NULL);
1071 return *this;
1074 void SwFltShell::NextParagraph()
1076 GetDoc().AppendTxtNode(*pPaM->GetPoint());
1079 void SwFltShell::NextPage()
1081 NextParagraph();
1082 GetDoc().Insert(*pPaM, SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK), 0);
1085 SwFltShell& SwFltShell::AddGraphic( const String& rPicName )
1087 // embedded:
1088 GraphicFilter* pFilter = ::GetGrfFilter();
1089 Graphic aGraphic;
1090 // one of: GFF_NOT GFF_BMP GFF_GIF GFF_JPG GFF_PCD GFF_PCX GFF_PNG
1091 // GFF_TIF GFF_XBM GFF_DXF GFF_MET GFF_PCT GFF_SGF GFF_SVM GFF_WMF
1092 // GFF_SGV GFF_XXX
1093 INetURLObject aDir(
1094 URIHelper::SmartRel2Abs(
1095 INetURLObject(GetBaseURL()), rPicName,
1096 URIHelper::GetMaybeFileHdl()) );
1097 switch (pFilter->ImportGraphic(aGraphic, aDir))
1099 case GRFILTER_OK:
1100 *this << aGraphic;
1101 break;
1102 case GRFILTER_OPENERROR:
1103 case GRFILTER_IOERROR:
1104 case GRFILTER_FORMATERROR:
1105 case GRFILTER_VERSIONERROR:
1106 case GRFILTER_FILTERERROR:
1107 case GRFILTER_ABORT:
1108 case GRFILTER_TOOBIG:
1109 default:
1110 AddError( "picture import error" );
1111 break;
1113 return *this;
1116 SwFltShell& SwFltShell::SetStyle( USHORT nStyle )
1118 SwFltFormatCollection* p = pColls[ nStyle ];
1120 if (p)
1122 if( !pOutDoc->IsInTable() && nStyle != nAktStyle )
1124 if( pColls[nAktStyle]->IsInFly() && pOutDoc->IsInFly() )
1125 pOutDoc->EndFly();
1126 if( p->IsInFly() )
1127 p->BeginStyleFly( pOutDoc );
1129 GetDoc().SetTxtFmtColl(*pPaM, p->GetColl());
1130 nAktStyle = nStyle;
1132 else
1134 ASSERT( FALSE, "Ungueltiger SwFltStyleCode" );
1136 return *this;
1139 SwFltShell& SwFltShell::operator << (SwFltBookmark& aBook)
1141 ConvertUStr( aBook.aName );
1142 aBook.aVal = QuoteStr(aBook.aVal);
1143 aEndStack.NewAttr(*pPaM->GetPoint(), aBook);
1144 return *this;
1147 void SwFltShell::SetBookEnd(long nHandle)
1149 aEndStack.SetAttr( *pPaM->GetPoint(), RES_FLTR_BOOKMARK, TRUE, nHandle );
1152 SwFltShell& SwFltShell::EndItem( USHORT nAttrId )
1154 switch( nAttrId )
1156 case RES_FLTR_BOOKMARK:
1157 ASSERT( FALSE, "Falscher Aufruf fuer Bookmark-Ende" );
1158 break;
1160 case RES_FLTR_TOX:
1161 aEndStack.SetAttr(*pPaM->GetPoint(), nAttrId);
1162 break;
1164 default:
1165 aStack.SetAttr(*pPaM->GetPoint(), nAttrId);
1166 break;
1168 return *this;
1171 SwFltShell& SwFltShell::operator << (const SwField& rField)
1173 GetDoc().Insert(*pPaM, SwFmtFld(rField), 0);
1174 return *this;
1177 /*virtual*/ SwFltOutBase& SwFltOutDoc::operator << (const SfxPoolItem& rItem)
1179 rStack.NewAttr(*pPaM->GetPoint(), rItem);
1180 return *this;
1183 /*virtual*/ SwFltOutBase& SwFltFormatCollection::operator <<
1184 (const SfxPoolItem& rItem)
1186 pColl->SetFmtAttr(rItem);
1187 return *this;
1190 const SfxPoolItem& SwFltOutDoc::GetAttr(USHORT nWhich)
1192 return *rStack.GetFmtAttr(*pPaM->GetPoint(), nWhich);
1195 const SfxPoolItem& SwFltFormatCollection::GetAttr(USHORT nWhich)
1197 return GetColl()->GetFmtAttr(nWhich); // mit Parents
1200 // GetNodeOrStyAttr holt Attribute fuer Toggle- und Modify-Attribute:
1201 // Bei Formatdefinitionen aus dem altuellen Style mit Parents
1202 // sonst aus dem Node mit Parents
1203 // Im Stack wird nicht nachgesehen
1205 const SfxPoolItem& SwFltOutDoc::GetNodeOrStyAttr(USHORT nWhich)
1207 SwCntntNode * pNd = GetDoc().GetNodes()[ pPaM->GetPoint()->nNode ]
1208 ->GetCntntNode();
1209 if (pNd) // ContentNode: Attribut mit Parent
1210 return pNd->GetAttr(nWhich);
1211 else // kein ContentNode, dann das dflt. Attribut
1212 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1215 const SfxPoolItem& SwFltFormatCollection::GetNodeOrStyAttr(USHORT nWhich)
1217 return GetColl()->GetFmtAttr(nWhich); // mit Parents
1220 const SfxPoolItem& SwFltShell::GetNodeOrStyAttr(USHORT nWhich)
1222 return pOut->GetNodeOrStyAttr( nWhich );
1225 const SfxPoolItem& SwFltShell::GetAttr(USHORT nWhich)
1227 return pOut->GetAttr( nWhich );
1230 const SfxPoolItem& SwFltShell::GetFlyFrmAttr(USHORT nWhich)
1232 return pOut->GetFlyFrmAttr( nWhich );
1235 SwFieldType* SwFltShell::GetSysFldType(USHORT eWhich)
1237 return GetDoc().GetSysFldType(eWhich);
1240 BOOL SwFltShell::GetWeightBold()
1242 return ((SvxWeightItem&)GetNodeOrStyAttr(RES_CHRATR_WEIGHT)).GetWeight()
1243 != WEIGHT_NORMAL;
1246 BOOL SwFltShell::GetPostureItalic()
1248 return ((SvxPostureItem&)GetNodeOrStyAttr(RES_CHRATR_POSTURE)).GetPosture()
1249 != ITALIC_NONE;
1252 BOOL SwFltShell::GetCrossedOut()
1254 return ((SvxCrossedOutItem&)GetNodeOrStyAttr(RES_CHRATR_CROSSEDOUT))
1255 .GetStrikeout() != STRIKEOUT_NONE;
1258 BOOL SwFltShell::GetContour()
1260 return ((SvxContourItem&)GetNodeOrStyAttr(RES_CHRATR_CONTOUR)).GetValue();
1263 BOOL SwFltShell::GetCaseKapitaelchen()
1265 return ((SvxCaseMapItem&)GetNodeOrStyAttr(RES_CHRATR_CASEMAP))
1266 .GetCaseMap() == SVX_CASEMAP_KAPITAELCHEN;
1269 BOOL SwFltShell::GetCaseVersalien()
1271 return ((SvxCaseMapItem&)GetNodeOrStyAttr(RES_CHRATR_CASEMAP))
1272 .GetCaseMap() == SVX_CASEMAP_VERSALIEN;
1275 //-------------------------------------------------------------------------
1276 // Tabellen
1277 //-------------------------------------------------------------------------
1279 SwFltOutBase::~SwFltOutBase()
1283 SwFltOutBase::SwFltOutBase(SwDoc& rDocu)
1284 : rDoc(rDocu), eFlyAnchor(FLY_AT_CNTNT), bFlyAbsPos(false)
1288 const SfxPoolItem& SwFltOutBase::GetCellAttr(USHORT nWhich)
1290 ASSERT(FALSE, "GetCellAttr ausserhalb von normalem Text");
1291 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1294 BOOL SwFltOutBase::BeginTable()
1296 ASSERT(FALSE, "BeginTable ausserhalb von normalem Text");
1297 return FALSE;
1300 void SwFltOutBase::NextTableCell()
1302 ASSERT(FALSE, "NextTableCell ausserhalb von normalem Text");
1305 void SwFltOutBase::NextTableRow()
1307 ASSERT(FALSE, "NextTableRow ausserhalb von normalem Text");
1310 void SwFltOutBase::SetTableWidth(SwTwips /*nW*/)
1312 ASSERT(FALSE, "SetTableWidth ausserhalb von normalem Text");
1315 void SwFltOutBase::SetTableOrient(sal_Int16 /*eOri*/)
1317 ASSERT(FALSE, "SetTableOrient ausserhalb von normalem Text");
1320 void SwFltOutBase::SetCellWidth(SwTwips /*nWidth*/, USHORT /*nCell*/)
1322 ASSERT(FALSE, "SetCellWidth ausserhalb von normalem Text");
1325 void SwFltOutBase::SetCellHeight(SwTwips /*nH*/)
1327 ASSERT(FALSE, "SetCellHeight ausserhalb von normalem Text");
1330 void SwFltOutBase::SetCellBorder(const SvxBoxItem& /*rFmtBox*/, USHORT /*nCell*/)
1332 ASSERT(FALSE, "SetCellBorder ausserhalb von normalem Text");
1335 void SwFltOutBase::SetCellSpace(USHORT /*nSp*/)
1337 ASSERT(FALSE, "SetCellSpace ausserhalb von normalem Text");
1340 void SwFltOutBase::DeleteCell(USHORT /*nCell*/)
1342 ASSERT(FALSE, "DeleteCell ausserhalb von normalem Text");
1345 void SwFltOutBase::EndTable()
1347 ASSERT(FALSE, "EndTable ausserhalb von normalem Text");
1350 /*virtual*/ BOOL SwFltOutDoc::IsInTable()
1352 return pTable != 0;
1355 BOOL SwFltOutDoc::BeginTable()
1357 if(bReadNoTbl)
1358 return FALSE;
1360 if (pTable){
1361 ASSERT(FALSE, "BeginTable in Table");
1362 return FALSE;
1364 // Alle Attribute schliessen, da sonst Attribute
1365 // entstehen koennen, die in Flys reinragen
1366 rStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1367 rEndStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1369 // create table:
1370 ASSERT(pTabSavedPos == NULL, "SwFltOutDoc");
1371 pTabSavedPos = new SwPosition(*pPaM->GetPoint());
1372 pTable = GetDoc().InsertTable(
1373 SwInsertTableOptions( tabopts::HEADLINE_NO_BORDER, 1 ),
1374 *pTabSavedPos, 1, 1, text::HoriOrientation::LEFT, 0, 0, FALSE, FALSE ); // TODO MULTIHEADER
1375 nTableWidth = 0;
1376 ((SwTable*)pTable)->LockModify(); // Nichts automatisch anpassen!
1377 // set pam in 1. table cell
1378 usTableX =
1379 usTableY = 0;
1380 SeekCell(usTableY, usTableX, TRUE);
1381 return TRUE;
1384 SwTableBox* SwFltOutDoc::GetBox(USHORT ny, USHORT nx /*= USHRT_MAX */)
1386 if(!pTable){
1387 ASSERT(pTable, "GetBox ohne Tabelle");
1388 return 0;
1390 if( nx == USHRT_MAX ) // aktuelle Zelle
1391 nx = usTableX;
1393 // get structs to table cells
1394 const SwTableLines* pTableLines = &pTable->GetTabLines();
1395 if(!pTableLines){
1396 ASSERT(FALSE, "SwFltOutDoc:GetBox:pTableLines");
1397 return 0;
1399 if( ny >= pTableLines->Count() ){ // Notbremse
1400 ASSERT( FALSE, "SwFltOutDoc:GetBox:ny >= Count()");
1401 ny = pTableLines->Count() - 1;
1403 SwTableLine* pTableLine = (*pTableLines)[ny];
1404 if(!pTableLine){
1405 ASSERT(FALSE, "SwFltOutDoc:GetBox:pTableLine");
1406 return 0;
1408 SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes();
1409 if(!pTableBoxes){
1410 ASSERT(FALSE, "SwFltOutDoc:GetBox:pTableBoxes");
1411 return 0;
1413 if( nx >= pTableBoxes->Count() ){ // Notbremse
1414 ASSERT(FALSE, "SwFltOutDoc:GetBox:nx >= Count()");
1415 nx = pTableBoxes->Count() - 1;
1417 SwTableBox* pTableBox = (*pTableBoxes)[nx];
1419 ASSERT(pTableBox != 0, "SwFltOutDoc:GetBox:pTableBox");
1420 return pTableBox;
1423 void SwFltOutDoc::NextTableCell()
1425 if(!pTable){
1426 ASSERT(pTable, "NextTableCell ohne Tabelle");
1427 return;
1429 const SwTableLines* pTableLines = &pTable->GetTabLines();
1430 SwTableLine* pTableLine = (*pTableLines)[usTableY];
1431 SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes();
1432 SwTableBox* pTableBox = (*pTableBoxes)[usTableX];
1433 ASSERT(pTableBox != 0, "SwFltOutDoc:NextTableCell:pTableBox");
1434 if(!pTableBox)
1435 return;
1436 //#pragma message(__FILE__ "(?) : Sw's const problem")
1437 // insert cells:
1438 if (++usTableX >= pTableBoxes->Count())
1439 GetDoc().GetNodes().InsBoxen(
1440 GetDoc().IsIdxInTbl(pPaM->GetPoint()->nNode),
1441 pTableLine,
1442 (SwTableBoxFmt*)pTableBox->GetFrmFmt(),
1443 GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ),
1445 pTableBoxes->Count());
1446 SeekCell(usTableY, usTableX, TRUE);
1447 pTableBox = (*pTableBoxes)[usTableX];
1448 ASSERT(pTableBox != 0, "SwFltOutDoc:pTableBox");
1449 if(pTableBox)
1450 (*pTableBoxes)[usTableX]->ClaimFrmFmt();
1453 void SwFltOutDoc::NextTableRow()
1455 SwTableBox* pTableBox = GetBox(usTableY, 0);
1456 if (pTableBox)
1458 // duplicate row:
1459 SwSelBoxes aSelBoxes;
1460 aSelBoxes.Insert( pTableBox );
1461 GetDoc().InsertRow(aSelBoxes);
1462 usTableX = 0;
1463 SeekCell(++usTableY, usTableX, TRUE);
1464 GetDoc().SetTxtFmtColl(*pPaM,
1465 GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ));
1469 void SwFltOutDoc::SetTableWidth(SwTwips nSwWidth)
1471 if(!pTable){
1472 ASSERT(pTable, "SetTableWidth ohne Tabelle");
1473 return;
1475 ASSERT( nSwWidth > MINLAY, "Tabellenbreite <= MINLAY" );
1476 if( nSwWidth != nTableWidth ){
1477 if( nTableWidth ) // Nicht beim ersten Setzen
1478 SplitTable();
1479 pTable->GetFrmFmt()->SetFmtAttr( SwFmtFrmSize(ATT_VAR_SIZE, nSwWidth));
1480 nTableWidth = nSwWidth;
1484 void SwFltOutDoc::SetTableOrient(sal_Int16 eOri)
1486 if(!pTable){
1487 ASSERT(pTable, "SetTableOrient ohne Tabelle");
1488 return;
1490 pTable->GetFrmFmt()->SetFmtAttr( SwFmtHoriOrient( 0, eOri ));
1493 void SwFltOutDoc::SetCellWidth(SwTwips nWidth, USHORT nCell /* = USHRT_MAX */ )
1495 if(!pTable){
1496 ASSERT(pTable, "SetCellWidth ohne Tabelle");
1497 return;
1499 ASSERT( nWidth > MINLAY, "Tabellenzellenbreite <= MINLAY" );
1500 if (nWidth < MINLAY)
1501 nWidth = MINLAY;
1503 SwTableBox* pTableBox = GetBox(usTableY, nCell);
1504 if(pTableBox && pTableBox->GetFrmFmt() ){
1505 SwFmtFrmSize aFmtFrmSize(ATT_FIX_SIZE);
1506 aFmtFrmSize.SetWidth(nWidth);
1507 pTableBox->GetFrmFmt()->SetFmtAttr(aFmtFrmSize);
1511 void SwFltOutDoc::SetCellHeight(SwTwips nHeight)
1513 if(!pTable){
1514 ASSERT(pTable, "SetCellHeight ohne Tabelle");
1515 return;
1518 const SwTableLines* pTableLines = &pTable->GetTabLines();
1519 SwTableLine* pTableLine = (*pTableLines)[usTableY];
1520 SwFmtFrmSize aFmtFrmSize(ATT_MIN_SIZE, 0, 0);
1521 if (nHeight < MINLAY)
1522 nHeight = MINLAY;
1523 aFmtFrmSize.SetHeight(nHeight);
1524 pTableLine->GetFrmFmt()->SetFmtAttr(aFmtFrmSize);
1527 const SfxPoolItem& SwFltOutDoc::GetCellAttr(USHORT nWhich)
1529 if (!pTable){
1530 ASSERT(pTable, "GetCellAttr ohne Table");
1531 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1534 SwTableBox* pTableBox = GetBox(usTableY, usTableX);
1535 if(!pTableBox)
1536 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1537 return pTableBox->GetFrmFmt()->GetFmtAttr( nWhich );
1540 void SwFltOutDoc::SetCellBorder(const SvxBoxItem& rFmtBox,
1541 USHORT nCell /* = USHRT_MAX */ )
1543 SwTableBox* pTableBox = GetBox(usTableY, nCell);
1544 if(pTableBox)
1545 pTableBox->GetFrmFmt()->SetFmtAttr(rFmtBox);
1548 // nicht aktiviert !!!
1549 void SwFltOutDoc::SetCellSpace(USHORT nDist)
1551 if(!pTable){
1552 ASSERT(pTable, "SetCellSpace ohne Tabelle");
1553 return;
1555 SwTableBox* pTableBox = GetBox(usTableY, usTableX);
1556 if(!pTableBox)
1557 return;
1559 SvxBoxItem aFmtBox( *((SvxBoxItem*)
1560 &pTableBox->GetFrmFmt()->GetFmtAttr( RES_BOX )));
1562 // versteh ich nich, sven: if (!nDist) nDist = 18; // ca. 0.03 cm
1563 if (nDist > 42) // max. 0.7 mm
1564 nDist = 42;
1565 else
1566 if (nDist < MIN_BORDER_DIST)
1567 nDist = MIN_BORDER_DIST;
1568 aFmtBox.SetDistance(nDist);
1569 pTableBox->GetFrmFmt()->SetFmtAttr(aFmtBox);
1572 void SwFltOutDoc::DeleteCell(USHORT nCell /* = USHRT_MAX */)
1574 SwTableBox* pTableBox = GetBox(usTableY, nCell);
1575 if(pTableBox){
1576 SwSelBoxes aSelBoxes;
1577 aSelBoxes.Insert( pTableBox );
1578 GetDoc().DeleteRowCol(aSelBoxes);
1579 usTableX--;
1583 void SwFltOutDoc::SplitTable()
1585 if(!pTable)
1587 ASSERT(pTable, "SplitTable ohne Tabelle");
1588 return;
1590 SwTableBox* pAktBox = GetBox(usTableY, usTableX);
1591 SwTableBox* pSplitBox = GetBox(usTableY - 1, 0);
1592 GetDoc().GetNodes().SplitTable(SwNodeIndex(*pSplitBox->GetSttNd()), false);
1593 pTable = &pAktBox->GetSttNd()->FindTableNode()->GetTable();
1594 usTableY = 0;
1597 void SwFltOutDoc::EndTable()
1599 if (!pTable){
1600 ASSERT(pTable, "EndTable ohne Table");
1601 return;
1603 // Alle Attribute schliessen, da sonst Attribute
1604 // entstehen koennen, die in Flys reinragen
1605 rStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1606 rEndStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1608 if (GetDoc().GetRootFrm()){
1609 SwTableNode* pTableNode = GetDoc().IsIdxInTbl(
1610 pPaM->GetPoint()->nNode);
1611 pTableNode->DelFrms();
1612 pTableNode->MakeFrms(&pPaM->GetPoint()->nNode);
1615 *pPaM->GetPoint() = *pTabSavedPos; // restore Cursor
1616 delete pTabSavedPos;
1617 pTabSavedPos = 0;
1618 ((SwTable*)pTable)->UnlockModify(); // Test, nuetzt nichts gegen Assert
1619 pTable = 0;
1620 nTableWidth = 0;
1623 BOOL SwFltOutDoc::SeekCell(short nRow, short nCol, BOOL bPam)
1625 // get structs to table cells
1626 const SwTableLines* pTableLines = &pTable->GetTabLines();
1627 SwTableLine* pTableLine = (*pTableLines)[usTableY];
1628 SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes();
1629 SwTableBox* pTableBox = (*pTableBoxes)[usTableX];
1631 if ((USHORT)nRow >= pTableLines->Count())
1633 ASSERT((USHORT)nRow >= pTableLines->Count(), "SwFltOutDoc");
1634 return FALSE;
1636 pTableLine = (*pTableLines)[nRow];
1637 pTableBoxes = &pTableLine->GetTabBoxes();
1638 if (nCol >= pTableBoxes->Count())
1639 return FALSE;
1640 pTableBox = (*pTableBoxes)[nCol];
1641 if( !pTableBox->GetSttNd() )
1643 ASSERT(pTableBox->GetSttNd(), "SwFltOutDoc");
1644 return FALSE;
1646 if(bPam)
1648 pPaM->GetPoint()->nNode = pTableBox->GetSttIdx() + 1;
1649 pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
1650 //#pragma message(__FILE__ "(?) : Sw's const problem")
1651 #if OSL_DEBUG_LEVEL > 1
1652 const SwTxtFmtColl* p = GetDoc().GetDfltTxtFmtColl();
1653 p = GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false );
1654 #endif
1655 GetDoc().SetTxtFmtColl(*pPaM,
1656 GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ));
1658 return TRUE;
1662 //-----------------------------------------------------------------------------
1663 // Flys in SwFltOutBase
1664 //-----------------------------------------------------------------------------
1666 SfxItemSet* SwFltOutBase::NewFlyDefaults()
1668 // Unbedingt noetige Standardwerte setzen ( falls diese Werte nicht
1669 // spaeter explizit gesetzt werden )
1671 SfxItemSet* p = new SfxItemSet( GetDoc().GetAttrPool(),
1672 RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
1673 SwFmtFrmSize aSz( ATT_VAR_SIZE, MINFLY, MINFLY );
1674 // Default: Breite 100% ( = PMW:Auto )
1675 aSz.SetWidthPercent( 100 ); // Hoehe: Auto
1676 p->Put( aSz );
1677 p->Put( SwFmtHoriOrient( 0, text::HoriOrientation::NONE, text::RelOrientation::FRAME ));
1678 return p;
1681 BOOL SwFltOutBase::BeginFly( RndStdIds eAnchor /*= FLY_AT_CNTNT*/,
1682 BOOL bAbsolutePos /*= FALSE*/,
1683 const SfxItemSet*
1684 #ifndef PRODUCT
1685 pMoreAttrs /*= 0*/
1686 #endif
1689 ASSERT(!pMoreAttrs, "SwFltOutBase:BeginFly mit pMoreAttrs" );
1690 eFlyAnchor = eAnchor;
1691 bFlyAbsPos = bAbsolutePos; // Bloedsinn eigentlich
1692 return TRUE;
1695 /*virtual*/ void SwFltOutBase::SetFlyAnchor( RndStdIds eAnchor )
1697 if( !IsInFly() ){
1698 ASSERT( FALSE, "SetFlyAnchor() ohne Fly" );
1699 return;
1701 if( eAnchor == FLY_IN_CNTNT ){
1702 ASSERT( FALSE, "SetFlyAnchor( FLY_IN_CNTNT ) nicht implementiert" );
1703 return;
1705 SwFmtAnchor& rAnchor = (SwFmtAnchor&)GetFlyFrmAttr( RES_ANCHOR );
1706 rAnchor.SetType( eAnchor );
1709 void SwFltOutBase::EndFly()
1711 if( bFlyAbsPos ){
1712 // hier muessen die absoluten Positionen am Fly noch in
1713 // die Writer-Koordinaten umgerechnet werden.
1717 //-----------------------------------------------------------------------------
1718 // Flys in SwFltDoc
1719 //-----------------------------------------------------------------------------
1721 /* virtual */ BOOL SwFltOutDoc::IsInFly()
1723 return pFly != 0;
1726 SwFrmFmt* SwFltOutDoc::MakeFly( RndStdIds eAnchor, SfxItemSet* pSet )
1728 pFly = (SwFlyFrmFmt*)GetDoc().MakeFlySection( eAnchor, pPaM->GetPoint(),
1729 pSet );
1730 return pFly;
1733 BOOL SwFltOutDoc::BeginFly( RndStdIds eAnchor /*= FLY_AT_CNTNT*/,
1734 BOOL bAbsolutePos /*= FALSE*/,
1735 const SfxItemSet* pMoreAttrs /*= 0*/ )
1738 SwFltOutBase::BeginFly( eAnchor, bAbsolutePos, 0 );
1739 SfxItemSet* pSet = NewFlyDefaults();
1741 // Alle Attribute schliessen, da sonst Attribute entstehen koennen,
1742 // die in Flys reinragen
1743 rStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1744 rEndStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1746 // create Fly:
1747 ASSERT(pFlySavedPos == NULL, "BeginFly in Fly"); // rekursiv geht noch nicht
1748 pFlySavedPos = new SwPosition(*pPaM->GetPoint());
1751 SwFmtAnchor aAnchor( eAnchor, 1 );
1753 // Wenn Fly-Attribute im Style waren, dann jetzt als Defaults reinsetzen
1754 if (pMoreAttrs)
1755 pSet->Put(*pMoreAttrs);
1757 // dieses NICHT bei Seitengebundenem Fly mit Seiten-NUMMER !
1758 aAnchor.SetAnchor(pPaM->GetPoint()); // braucht erstaunlicherweise
1759 // den Stack nicht
1760 // aStack.NewAttr( *pPaM->GetPoint(), SwFltAnchor( pFly ) );
1762 pSet->Put( aAnchor );
1763 SwFrmFmt* pF = MakeFly( eAnchor, pSet );
1764 delete pSet;
1766 // set pam in Fly
1767 const SwFmtCntnt& rCntnt = pF->GetCntnt();
1768 ASSERT( rCntnt.GetCntntIdx(), "Kein Inhalt vorbereitet." );
1769 pPaM->GetPoint()->nNode = rCntnt.GetCntntIdx()->GetIndex() + 1;
1770 SwCntntNode *pNode = pPaM->GetCntntNode();
1771 pPaM->GetPoint()->nContent.Assign( pNode, 0 );
1773 return TRUE;
1776 /*virtual*/ void SwFltOutDoc::SetFlyFrmAttr(const SfxPoolItem& rAttr)
1778 if (pFly){
1779 pFly->SetFmtAttr( rAttr );
1780 }else{
1781 ASSERT(pFly, "SetFlyAttr ohne Doc-Fly");
1782 return;
1786 /*virtual*/ const SfxPoolItem& SwFltOutDoc::GetFlyFrmAttr(USHORT nWhich)
1788 if (pFly){
1789 return pFly->GetFmtAttr( nWhich );
1790 }else{
1791 ASSERT(pFly, "GetFlyAttr ohne Fly");
1792 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1796 void SwFltOutDoc::EndFly()
1798 if( pTable ){
1799 ASSERT( FALSE, "SwFltOutDoc::EndFly() in Table" );
1800 return;
1802 // Alle Attribute schliessen, da sonst Attribute
1803 // entstehen koennen, die aus Flys rausragen
1804 rStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1805 rEndStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1807 *pPaM->GetPoint() = *pFlySavedPos; // restore Cursor
1808 delete pFlySavedPos;
1809 pFlySavedPos = 0;
1810 SwFltOutBase::EndFly();
1811 pFly = 0;
1814 //-----------------------------------------------------------------------------
1815 // Flys in SwFltFormatCollection
1816 //-----------------------------------------------------------------------------
1817 /*virtual*/ BOOL SwFltFormatCollection::IsInFly()
1819 return bHasFly;
1822 /*virtual*/ void SwFltFormatCollection::SetFlyFrmAttr(const SfxPoolItem& rAttr)
1824 if (!pFlyAttrs)
1825 pFlyAttrs = new SfxItemSet( GetDoc().GetAttrPool(),
1826 RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
1827 pFlyAttrs->Put( rAttr );
1830 /*virtual*/ const SfxPoolItem& SwFltFormatCollection::GetFlyFrmAttr(USHORT nWhich)
1832 // ASSERT( pFlyAttrs, "GetFlyFrmAttr ohne Coll-FlyAttrs" );
1833 if( pFlyAttrs )
1834 return pFlyAttrs->Get( nWhich, FALSE );
1835 else
1836 return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1839 BOOL SwFltFormatCollection::BeginFly( RndStdIds eAnchor /*= FLY_AT_CNTNT*/,
1840 BOOL bAbsolutePos /*= FALSE*/,
1841 const SfxItemSet* pMoreAttrs /*= 0*/ )
1844 SwFltOutBase::BeginFly( eAnchor, bAbsolutePos, pMoreAttrs );
1845 bHasFly = TRUE;
1846 return TRUE;
1849 void SwFltFormatCollection::EndFly() // Wird nie aufgerufen
1853 BOOL SwFltFormatCollection::BeginStyleFly( SwFltOutDoc* pOutDoc )
1855 ASSERT( pOutDoc, "BeginStyleFly ohne pOutDoc" );
1856 ASSERT( pOutDoc && !pOutDoc->IsInFly(), "BeginStyleFly in Fly" );
1857 if( pOutDoc && !pOutDoc->IsInFly() )
1858 return pOutDoc->BeginFly( eFlyAnchor, bFlyAbsPos, pFlyAttrs );
1859 else
1860 return FALSE;
1863 //-----------------------------------------------------------------------------
1864 // Flys in SwFltShell
1865 //-----------------------------------------------------------------------------
1867 BOOL SwFltShell::BeginFly( RndStdIds eAnchor /*= FLY_AT_CNTNT*/,
1868 BOOL bAbsolutePos /*= FALSE*/ )
1871 if (pOut->IsInFly()){
1872 ASSERT(FALSE, "BeginFly in Fly");
1873 return FALSE;
1875 if (pOutDoc->IsInTable()){
1876 ASSERT(FALSE, "BeginFly in Table");
1877 return FALSE;
1879 pOut->BeginFly( eAnchor, bAbsolutePos, pColls[nAktStyle]->GetpFlyAttrs() );
1880 eSubMode = Fly;
1881 return TRUE;
1884 void SwFltShell::SetFlyXPos( short nXPos, sal_Int16 eHRel /*= text::RelOrientation::FRAME*/,
1885 sal_Int16 eHAlign /*= text::HoriOrientation::NONE*/ )
1887 SetFlyFrmAttr( SwFmtHoriOrient( nXPos, eHAlign, eHRel ) );
1890 void SwFltShell::SetFlyYPos( short nYPos, sal_Int16 eVRel /*= text::RelOrientation::FRAME*/,
1891 sal_Int16 eVAlign /*= text::VertOrientation::NONE*/ )
1893 SetFlyFrmAttr( SwFmtVertOrient( nYPos, eVAlign, eVRel ) );
1897 void SwFltShell::EndFly()
1899 if (!pOut->IsInFly()){
1900 ASSERT(FALSE, "EndFly ohne Fly");
1901 return;
1903 if (pOutDoc->IsInTable()){ // Table verschraenkt mit Fly macht keinen Sinn
1904 ASSERT(FALSE, "EndFly in Table ( verschraenkt )");
1905 EndTable(); // -> Table beenden
1907 pOut->EndFly();
1908 eSubMode = None;
1911 //-----------------------------------------------------------------------------
1912 // Fussnoten
1913 //-----------------------------------------------------------------------------
1915 void SwFltShell::BeginFootnote()
1917 if( pOut->IsInFly() ){ // Passiert z.B. bei Fussnote in Fly
1918 ASSERT(FALSE, "Fussnote in Fly nicht erlaubt");
1919 return;
1921 if( pOutDoc->IsInTable() ){
1922 ASSERT(FALSE, "Fussnote in Table z.Zt. nicht erlaubt");
1923 return;
1926 // Alle Attribute schliessen, da sonst Attribute entstehen koennen,
1927 // die in Fussnoten reinragen
1928 aStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1929 // aEndStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1930 // EndStack erstmal nicht zwangs-Schliessen, damit Bookmarks ueber
1931 // Fussnoten im PMW uebernommen werden
1933 SwFmtFtn aFtn;
1934 GetDoc().Insert(*pPaM, aFtn, 0);
1935 ASSERT(pSavedPos == NULL, "SwFltShell");
1936 pSavedPos = new SwPosition(*pPaM->GetPoint());
1937 pPaM->Move(fnMoveBackward, fnGoCntnt);
1938 SwTxtNode* pTxt = pPaM->GetNode()->GetTxtNode();
1939 SwTxtAttr* pFN = pTxt->GetTxtAttr(pPaM->GetPoint()->nContent,
1940 RES_TXTATR_FTN);
1941 if( !pFN ){ // Passiert z.B. bei Fussnote in Fly
1942 ASSERT(pFN, "Probleme beim Anlegen des Fussnoten-Textes");
1943 return;
1945 const SwNodeIndex* pStartIndex = ((SwTxtFtn*)pFN)->GetStartNode();
1946 ASSERT(pStartIndex, "Probleme beim Anlegen des Fussnoten-Textes");
1947 pPaM->GetPoint()->nNode = pStartIndex->GetIndex() + 1;
1948 pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
1949 eSubMode = Footnote;
1952 void SwFltShell::EndFootnote()
1954 if(!pSavedPos)
1955 return;
1956 // Alle Attribute schliessen, da sonst Attribute
1957 // entstehen koennen, die aus Fussnoten rausragen
1958 aStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1959 // aEndStack.SetAttr( *pPaM->GetPoint(), 0, FALSE );
1960 // EndStack erstmal nicht zwangs-Schliessen, damit Bookmarks ueber
1961 // Fussnoten im PMW uebernommen werden
1963 *pPaM->GetPoint() = *pSavedPos; // restore Cursor
1964 delete pSavedPos;
1965 pSavedPos = 0;
1968 void SwFltShell::BeginHeader(SwPageDesc* /*pPD*/)
1970 SwFrmFmt* pFmt = &pCurrentPageDesc->GetMaster(
1971 ); //(bUseLeft) ? &pCurrentPageDesc->GetLeft() :
1972 SwFrmFmt* pHdFtFmt;
1973 pFmt->SetFmtAttr(SwFmtHeader(TRUE));
1974 pHdFtFmt = (SwFrmFmt*)pFmt->GetHeader().GetHeaderFmt();
1975 const SwNodeIndex* pStartIndex = pHdFtFmt->GetCntnt().GetCntntIdx();
1976 if (!pStartIndex)
1977 return;
1978 ASSERT(pSavedPos == NULL, "SwFltShell");
1979 pSavedPos = new SwPosition(*pPaM->GetPoint());
1980 pPaM->GetPoint()->nNode = pStartIndex->GetIndex() + 1;
1981 pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
1982 eSubMode = Header;
1985 void SwFltShell::BeginFooter(SwPageDesc* /*pPD*/)
1987 SwFrmFmt* pFmt = &pCurrentPageDesc->GetMaster(
1988 ); //(bUseLeft) ? &pCurrentPageDesc->GetLeft() :
1989 SwFrmFmt* pHdFtFmt;
1990 pFmt->SetFmtAttr(SwFmtFooter(TRUE));
1991 pHdFtFmt = (SwFrmFmt*)pFmt->GetFooter().GetFooterFmt();
1992 const SwNodeIndex* pStartIndex = pHdFtFmt->GetCntnt().GetCntntIdx();
1993 if (!pStartIndex)
1994 return;
1995 ASSERT(pSavedPos == NULL, "SwFltShell");
1996 pSavedPos = new SwPosition(*pPaM->GetPoint());
1997 pPaM->GetPoint()->nNode = pStartIndex->GetIndex() + 1;
1998 pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
1999 eSubMode = Footer;
2002 void SwFltShell::EndHeaderFooter()
2004 *pPaM->GetPoint() = *pSavedPos; // restore Cursor
2005 delete pSavedPos;
2006 pSavedPos = 0;
2009 SwPageDesc* SwFltShell::MakePageDesc(SwPageDesc* pFirstPageDesc)
2011 if(bStdPD) // keine Neuen PageDescs
2012 return pCurrentPageDesc;
2014 BOOL bFollow = (pFirstPageDesc != 0);
2015 SwPageDesc* pNewPD;
2016 USHORT nPos;
2017 if (bFollow && pFirstPageDesc->GetFollow() != pFirstPageDesc)
2018 return pFirstPageDesc; // Fehler: hat schon Follow
2019 // Erkennung doppelter Namen fehlt noch (Wahrscheinlichkeit
2020 // fuer dopp. Namen ist gering)
2022 nPos = GetDoc().MakePageDesc( ViewShell::GetShellRes()->GetPageDescName(
2023 GetDoc().GetPageDescCnt(), FALSE, bFollow ),
2024 pFirstPageDesc, FALSE );
2026 pNewPD = &((SwPageDesc&)const_cast<const SwDoc &>(GetDoc()).
2027 GetPageDesc(nPos));
2028 if (bFollow)
2029 { // Dieser ist der folgende von pPageDesc
2030 pFirstPageDesc->SetFollow(pNewPD);
2031 pNewPD->SetFollow(pNewPD);
2033 else
2034 GetDoc().Insert( *pPaM, SwFmtPageDesc( pNewPD ), 0 );
2035 pNewPD->WriteUseOn( // alle Seiten
2036 (UseOnPage)(nsUseOnPage::PD_ALL | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE));
2037 return pNewPD;
2040 ///////////////////////////////////////////////// SwFltFormatCollection
2041 SwFltFormatCollection::SwFltFormatCollection(
2042 SwDoc& _rDoc, RES_POOL_COLLFMT_TYPE nType ) :
2043 SwFltOutBase(_rDoc),
2044 pColl(_rDoc.GetTxtCollFromPool( static_cast< sal_uInt16 >(nType), false )),
2045 pFlyAttrs( 0 ),
2046 bHasFly( FALSE )
2048 Reset(); // Default-Attrs loeschen und Auto-Flag
2051 SwFltFormatCollection::SwFltFormatCollection(
2052 SwDoc& _rDoc, const String& rName ) :
2053 SwFltOutBase(_rDoc),
2054 pFlyAttrs( 0 ),
2055 bHasFly( FALSE )
2057 pColl = _rDoc.MakeTxtFmtColl(rName, (SwTxtFmtColl*)_rDoc.GetDfltTxtFmtColl());
2058 Reset(); // Default-Attrs loeschen und Auto-Flag
2061 void SwFltShell::NextStyle(USHORT nWhich, USHORT nNext)
2063 ASSERT(pColls[nWhich], "Next style for noexistent style" );
2064 ASSERT(pColls[nNext], "Next style to noexistent style" );
2065 if( pColls[nWhich] && pColls[nNext] )
2066 pColls[nWhich]->GetColl()->SetNextTxtFmtColl(
2067 *pColls[nNext]->GetColl() );
2070 // UpdatePageDescs muss am Ende des Einlesevorganges aufgerufen werden, damit
2071 // der Writer den Inhalt der Pagedescs wirklich akzeptiert
2072 void UpdatePageDescs(SwDoc &rDoc, sal_uInt16 nInPageDescOffset)
2074 // Pagedescriptoren am Dokument updaten (nur so werden auch die
2075 // linken Seiten usw. eingestellt).
2077 // PageDesc "Standard"
2078 rDoc.ChgPageDesc(0, const_cast<const SwDoc &>(rDoc).GetPageDesc(0));
2080 // PageDescs "Konvert..."
2081 for (sal_uInt16 i = nInPageDescOffset; i < rDoc.GetPageDescCnt(); ++i)
2082 rDoc.ChgPageDesc(i, const_cast<const SwDoc &>(rDoc).GetPageDesc(i));
2085 /* vi:set tabstop=4 shiftwidth=4 expandtab: */