merge the formfield patch from ooo-build
[ooovba.git] / sw / source / filter / rtf / swparrtf.cxx
blob3e1950f40fe1a612ff44e471e56f1feb3cbf4091
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: swparrtf.cxx,v $
10 * $Revision: 1.81.82.1 $
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"
33 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
34 #include <hintids.hxx>
36 #include <stack>
38 #ifndef __RSC //autogen
39 #include <tools/errinf.hxx>
40 #endif
41 #include <tools/stream.hxx>
42 #include <svtools/itemiter.hxx>
43 #include <svtools/rtftoken.h>
44 #include <svtools/intitem.hxx>
45 #include <svx/fhgtitem.hxx>
46 #include <svx/ulspitem.hxx>
47 #ifndef _SVX_TSTPITEM_HXX //autogen
48 #include <svx/tstpitem.hxx>
49 #endif
50 #include <svx/lspcitem.hxx>
51 #include <svx/lrspitem.hxx>
52 #include <svx/escpitem.hxx>
53 #include <svx/fontitem.hxx>
54 #include <svx/frmdiritem.hxx>
55 #include <svx/hyznitem.hxx>
56 #include <fmtpdsc.hxx>
57 #include <fmtfld.hxx>
58 #include <fmthdft.hxx>
59 #include <fmtcntnt.hxx>
60 #include <txtftn.hxx>
61 #include <fmtclds.hxx>
62 #include <fmtftn.hxx>
63 #include <fmtfsize.hxx>
64 #include <fmtflcnt.hxx>
65 #include <fmtanchr.hxx>
66 #include <frmatr.hxx>
67 #include <docstat.hxx>
68 #include <swtable.hxx>
69 #include <shellio.hxx>
70 #include <swtypes.hxx>
71 #include <ndtxt.hxx>
72 #include <doc.hxx>
73 #include <docary.hxx>
74 #include <pam.hxx>
75 #include <mdiexp.hxx> // ...Percent()
76 #include <swparrtf.hxx>
77 #include <charfmt.hxx>
78 #include <pagedesc.hxx>
79 #include <ftninfo.hxx>
80 #include <docufld.hxx>
81 #include <flddat.hxx>
82 #include <fltini.hxx>
83 #include <fchrfmt.hxx>
84 #include <paratr.hxx>
85 #ifndef _SECTIOM_HXX
86 #include <section.hxx>
87 #endif
88 #include <fmtclbl.hxx>
89 #include <viewsh.hxx>
90 #include <shellres.hxx>
91 #include <hfspacingitem.hxx>
92 #include <tox.hxx>
93 #include <swerror.h>
94 #ifndef _CMDID_H
95 #include <cmdid.h>
96 #endif
97 #ifndef _STATSTR_HRC
98 #include <statstr.hrc> // ResId fuer Statusleiste
99 #endif
100 #include <SwStyleNameMapper.hxx>
101 #include <tblsel.hxx> // SwSelBoxes
103 #include <docsh.hxx>
104 #include <fmtlsplt.hxx> // SwLayoutSplit
105 #include <svx/keepitem.hxx>
106 #include <svx/svdopath.hxx>
107 #include <svx/svdorect.hxx>
110 #include <fmtsrnd.hxx>
111 #include <fmtfollowtextflow.hxx>
112 #include <svx/svdmodel.hxx>
113 #include <svx/svdpage.hxx>
114 #include <svx/opaqitem.hxx>
115 #include "svx/svdograf.hxx"
116 #include <svx/xflclit.hxx>
117 #include <svx/xlnwtit.hxx>
118 #include <svx/svdoutl.hxx>
119 #include <svx/outlobj.hxx>
120 #include <svx/paperinf.hxx>
122 #include <tools/stream.hxx>
123 #include <basegfx/polygon/b2dpolygon.hxx>
124 #include <basegfx/polygon/b2dpolypolygon.hxx>
125 #include <basegfx/range/b2drange.hxx>
126 #include <vcl/salbtype.hxx> // FRound
128 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
131 using namespace ::com::sun::star;
134 // einige Hilfs-Funktionen
135 // char
136 inline const SvxFontHeightItem& GetSize(const SfxItemSet& rSet,BOOL bInP=TRUE)
137 { return (const SvxFontHeightItem&)rSet.Get( RES_CHRATR_FONTSIZE,bInP); }
138 inline const SvxLRSpaceItem& GetLRSpace(const SfxItemSet& rSet,BOOL bInP=TRUE)
139 { return (const SvxLRSpaceItem&)rSet.Get( RES_LR_SPACE,bInP); }
141 /* \f */
143 extern "C" SAL_DLLPUBLIC_EXPORT Reader* SAL_CALL ImportRTF()
145 return new RtfReader();
148 // Aufruf fuer die allg. Reader-Schnittstelle
149 ULONG RtfReader::Read( SwDoc &rDoc, const String& rBaseURL, SwPaM &rPam, const String &)
151 if( !pStrm )
153 ASSERT( FALSE, "RTF-Read ohne Stream" );
154 return ERR_SWG_READ_ERROR;
157 //JP 18.01.96: Alle Ueberschriften sind normalerweise ohne
158 // Kapitelnummer. Darum hier explizit abschalten
159 // weil das Default jetzt wieder auf AN ist.
160 if( !bInsertMode )
162 Reader::SetNoOutlineNum( rDoc );
164 // MIB 27.09.96: Umrandung uns Abstaende aus Frm-Vorlagen entf.
165 Reader::ResetFrmFmts( rDoc );
168 ULONG nRet = 0;
169 SwDocShell *pDocShell(rDoc.GetDocShell());
170 DBG_ASSERT(pDocShell, "no SwDocShell");
171 uno::Reference<document::XDocumentProperties> xDocProps;
172 if (pDocShell) {
173 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
174 pDocShell->GetModel(), uno::UNO_QUERY_THROW);
175 xDocProps.set(xDPS->getDocumentProperties());
178 SvParserRef xParser = new SwRTFParser( &rDoc, xDocProps,
179 rPam, *pStrm, rBaseURL, !bInsertMode );
180 SvParserState eState = xParser->CallParser();
181 if( SVPAR_PENDING != eState && SVPAR_ACCEPTED != eState )
183 String sErr( String::CreateFromInt32( xParser->GetLineNr() ));
184 sErr += ',';
185 sErr += String::CreateFromInt32( xParser->GetLinePos() );
187 nRet = *new StringErrorInfo( ERR_FORMAT_ROWCOL, sErr,
188 ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
192 return nRet;
195 SwRTFParser::SwRTFParser(SwDoc* pD,
196 uno::Reference<document::XDocumentProperties> i_xDocProps,
197 const SwPaM& rCrsr, SvStream& rIn, const String& rBaseURL,
198 int bReadNewDoc) :
199 SvxRTFParser(pD->GetAttrPool(), rIn, i_xDocProps, bReadNewDoc),
200 maParaStyleMapper(*pD),
201 maCharStyleMapper(*pD),
202 maSegments(*this),
203 maInsertedTables(*pD),
204 aMergeBoxes(0, 5),
205 aTblFmts(0, 10),
206 mpBookmarkStart(0),
207 mpRedlineStack(0),
208 pAuthorInfos(0),
209 pGrfAttrSet(0),
210 pTableNode(0),
211 pOldTblNd(0),
212 pSttNdIdx(0),
213 pRegionEndIdx(0),
214 pDoc(pD),
215 pRelNumRule(new SwRelNumRuleSpaces(*pD, static_cast< BOOL >(bReadNewDoc))),
216 pRedlineInsert(0),
217 pRedlineDelete(0),
218 sBaseURL( rBaseURL ),
219 nAktPageDesc(0),
220 nAktFirstPageDesc(0),
221 nAktBox(0),
222 nInsTblRow(USHRT_MAX),
223 nNewNumSectDef(USHRT_MAX),
224 nRowsToRepeat(0),
225 // --> OD 2008-12-22 #i83368#
226 mbReadCellWhileReadSwFly( false ),
227 // <--
228 bTrowdRead(0),
229 nReadFlyDepth(0),
230 nZOrder(0)
232 mbIsFootnote = mbReadNoTbl = bReadSwFly = bSwPageDesc = bStyleTabValid =
233 bInPgDscTbl = bNewNumList = false;
234 bFirstContinue = true;
235 bContainsPara = false;
236 bContainsTablePara = false;
237 bNestedField = false;
238 bForceNewTable = false;
240 pPam = new SwPaM( *rCrsr.GetPoint() );
241 SetInsPos( SwxPosition( pPam ) );
242 SetChkStyleAttr( 0 != bReadNewDoc );
243 SetCalcValue( FALSE );
244 SetReadDocInfo( TRUE );
246 // diese sollen zusaetzlich ueber \pard zurueck gesetzt werden
247 USHORT temp;
248 temp = RES_TXTATR_CHARFMT; AddPlainAttr( temp );
249 temp = RES_PAGEDESC; AddPardAttr( temp );
250 temp = RES_BREAK; AddPardAttr( temp );
251 temp = RES_PARATR_NUMRULE; AddPardAttr( temp );
252 temp = FN_PARAM_NUM_LEVEL; AddPardAttr( temp );
255 // Aufruf des Parsers
256 SvParserState SwRTFParser::CallParser()
258 mbReadNoTbl = false;
259 bFirstContinue = true;
261 rInput.Seek(STREAM_SEEK_TO_BEGIN);
262 rInput.ResetError();
264 mpRedlineStack = new sw::util::RedlineStack(*pDoc);
266 return SvxRTFParser::CallParser();
269 bool lcl_UsedPara(SwPaM &rPam)
271 const SwCntntNode* pCNd;
272 const SfxItemSet* pSet;
273 if( rPam.GetPoint()->nContent.GetIndex() ||
274 ( 0 != ( pCNd = rPam.GetCntntNode()) &&
275 0 != ( pSet = pCNd->GetpSwAttrSet()) &&
276 ( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, FALSE ) ||
277 SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, FALSE ))))
278 return true;
279 return false;
282 void SwRTFParser::Continue( int nToken )
284 if( bFirstContinue )
286 bFirstContinue = FALSE;
288 if (IsNewDoc())
291 // COMPATIBILITY FLAGS START
293 pDoc->set(IDocumentSettingAccess::PARA_SPACE_MAX, true);
294 pDoc->set(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES, true);
295 pDoc->set(IDocumentSettingAccess::TAB_COMPAT, true);
296 pDoc->set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, true);
297 pDoc->set(IDocumentSettingAccess::USE_HIRES_VIRTUAL_DEVICE, true);
298 pDoc->set(IDocumentSettingAccess::ADD_FLY_OFFSETS, true);
299 pDoc->set(IDocumentSettingAccess::ADD_EXT_LEADING, true);
300 pDoc->set(IDocumentSettingAccess::OLD_NUMBERING, false);
301 pDoc->set(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, false );
302 pDoc->set(IDocumentSettingAccess::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, false);
303 pDoc->set(IDocumentSettingAccess::OLD_LINE_SPACING, false);
304 pDoc->set(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS, true);
305 pDoc->set(IDocumentSettingAccess::USE_FORMER_OBJECT_POS, false);
306 pDoc->set(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING, false);
307 pDoc->set(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION, true);
308 pDoc->set(IDocumentSettingAccess::DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, false); // --> FME 2005-08-11 #i53199#
309 // --> FME 2006-02-10 #131283#
310 pDoc->set(IDocumentSettingAccess::TABLE_ROW_KEEP, true);
311 pDoc->set(IDocumentSettingAccess::IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION, true);
312 pDoc->set(IDocumentSettingAccess::INVERT_BORDER_SPACING, true);
314 // COMPATIBILITY FLAGS END
318 // einen temporaeren Index anlegen, auf Pos 0 so wird er nicht bewegt!
319 pSttNdIdx = new SwNodeIndex( pDoc->GetNodes() );
320 if( !IsNewDoc() ) // in ein Dokument einfuegen ?
322 const SwPosition* pPos = pPam->GetPoint();
323 SwTxtNode* pSttNd = pPos->nNode.GetNode().GetTxtNode();
325 pDoc->SplitNode( *pPos, false );
327 *pSttNdIdx = pPos->nNode.GetIndex()-1;
328 pDoc->SplitNode( *pPos, false );
330 SwPaM aInsertionRangePam( *pPos );
332 pPam->Move( fnMoveBackward );
334 // #106634# split any redline over the insertion point
335 aInsertionRangePam.SetMark();
336 *aInsertionRangePam.GetPoint() = *pPam->GetPoint();
337 aInsertionRangePam.Move( fnMoveBackward );
338 pDoc->SplitRedline( aInsertionRangePam );
340 pDoc->SetTxtFmtColl( *pPam, pDoc->GetTxtCollFromPool
341 ( RES_POOLCOLL_STANDARD, false ));
343 // verhinder das einlesen von Tabellen in Fussnoten / Tabellen
344 ULONG nNd = pPos->nNode.GetIndex();
345 mbReadNoTbl = 0 != pSttNd->FindTableNode() ||
346 ( nNd < pDoc->GetNodes().GetEndOfInserts().GetIndex() &&
347 pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() < nNd );
350 // Laufbalken anzeigen, aber nur bei synchronem Call
351 ULONG nCurrPos = rInput.Tell();
352 rInput.Seek(STREAM_SEEK_TO_END);
353 rInput.ResetError();
354 ::StartProgress( STR_STATSTR_W4WREAD, 0, rInput.Tell(), pDoc->GetDocShell());
355 rInput.Seek( nCurrPos );
356 rInput.ResetError();
359 SvxRTFParser::Continue( nToken );
361 if( SVPAR_PENDING == GetStatus() )
362 return ; // weiter gehts beim naechsten mal
364 pRelNumRule->SetNumRelSpaces( *pDoc );
366 // den Start wieder korrigieren
367 if( !IsNewDoc() && pSttNdIdx->GetIndex() )
369 //die Flys muessen zuerst zurecht gerueckt werden, denn sonst wird
370 // ein am 1. Absatz verankerter Fly falsch eingefuegt
371 if( SVPAR_ACCEPTED == eState )
373 if( aFlyArr.Count() )
374 SetFlysInDoc();
375 pRelNumRule->SetOultineRelSpaces( *pSttNdIdx, pPam->GetPoint()->nNode );
378 SwTxtNode* pTxtNode = pSttNdIdx->GetNode().GetTxtNode();
379 SwNodeIndex aNxtIdx( *pSttNdIdx );
380 if( pTxtNode && pTxtNode->CanJoinNext( &aNxtIdx ))
382 xub_StrLen nStt = pTxtNode->GetTxt().Len();
383 // wenn der Cursor noch in dem Node steht, dann setze in an das Ende
384 if( pPam->GetPoint()->nNode == aNxtIdx )
386 pPam->GetPoint()->nNode = *pSttNdIdx;
387 pPam->GetPoint()->nContent.Assign( pTxtNode, nStt );
390 #ifndef PRODUCT
391 // !!! sollte nicht moeglich sein, oder ??
392 ASSERT( pSttNdIdx->GetIndex()+1 != pPam->GetBound( TRUE ).nNode.GetIndex(),
393 "Pam.Bound1 steht noch im Node" );
394 ASSERT( pSttNdIdx->GetIndex()+1 != pPam->GetBound( FALSE ).nNode.GetIndex(),
395 "Pam.Bound2 steht noch im Node" );
397 if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( TRUE ).nNode.GetIndex() )
399 xub_StrLen nCntPos = pPam->GetBound( TRUE ).nContent.GetIndex();
400 pPam->GetBound( TRUE ).nContent.Assign( pTxtNode,
401 pTxtNode->GetTxt().Len() + nCntPos );
403 if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( FALSE ).nNode.GetIndex() )
405 xub_StrLen nCntPos = pPam->GetBound( FALSE ).nContent.GetIndex();
406 pPam->GetBound( FALSE ).nContent.Assign( pTxtNode,
407 pTxtNode->GetTxt().Len() + nCntPos );
409 #endif
410 // Zeichen Attribute beibehalten!
411 SwTxtNode* pDelNd = aNxtIdx.GetNode().GetTxtNode();
412 if( pTxtNode->GetTxt().Len() )
413 pDelNd->FmtToTxtAttr( pTxtNode );
414 else
415 pTxtNode->ChgFmtColl( pDelNd->GetTxtColl() );
416 pTxtNode->JoinNext();
420 if( SVPAR_ACCEPTED == eState )
422 // den letzen Bereich wieder zumachen
423 if( pRegionEndIdx )
425 // JP 06.01.00: Task 71411 - the last section in WW are not a
426 // balanced Section.
427 if( !GetVersionNo() )
429 SwSectionNode* pSectNd = pRegionEndIdx->GetNode().
430 StartOfSectionNode()->GetSectionNode();
431 if( pSectNd )
432 pSectNd->GetSection().GetFmt()->SetFmtAttr(
433 SwFmtNoBalancedColumns( TRUE ) );
436 DelLastNode();
437 pPam->GetPoint()->nNode = *pRegionEndIdx;
438 pPam->Move( fnMoveForward, fnGoNode );
439 delete pRegionEndIdx, pRegionEndIdx = 0;
442 sal_uInt16 nPageDescOffset = pDoc->GetPageDescCnt();
443 maSegments.InsertSegments(IsNewDoc());
444 UpdatePageDescs(*pDoc, nPageDescOffset);
445 //$flr folloing garbe collecting code has been moved from the previous procedure
446 // UpdatePageDescs to here in order to fix bug #117882#
447 rtfSections::myrDummyIter aDEnd = maSegments.maDummyPageNos.rend();
448 for (rtfSections::myrDummyIter aI = maSegments.maDummyPageNos.rbegin(); aI != aDEnd; ++aI)
449 pDoc->DelPageDesc(*aI);
451 if( aFlyArr.Count() )
452 SetFlysInDoc();
454 // jetzt noch den letzten ueberfluessigen Absatz loeschen
455 SwPosition* pPos = pPam->GetPoint();
456 if( !pPos->nContent.GetIndex() )
458 SwTxtNode* pAktNd;
459 ULONG nNodeIdx = pPos->nNode.GetIndex();
460 if( IsNewDoc() )
462 SwNode* pTmp = pDoc->GetNodes()[ nNodeIdx -1 ];
463 if( pTmp->IsCntntNode() && !pTmp->FindTableNode() )
465 // --> FME 2006-02-15 #131200# Do not delete the paragraph
466 // if it has anchored objects:
467 bool bAnchoredObjs = false;
468 const SwSpzFrmFmts* pFrmFmts = pDoc->GetSpzFrmFmts();
469 if ( pFrmFmts && pFrmFmts->Count() )
471 for ( USHORT nI = pFrmFmts->Count(); nI; --nI )
473 const SwFmtAnchor & rAnchor = (*pFrmFmts)[ nI - 1 ]->GetAnchor();
474 if ( FLY_AT_CNTNT == rAnchor.GetAnchorId() ||
475 FLY_AUTO_CNTNT == rAnchor.GetAnchorId() )
477 const SwPosition * pObjPos = rAnchor.GetCntntAnchor();
478 if ( pObjPos && nNodeIdx == pObjPos->nNode.GetIndex() )
480 bAnchoredObjs = true;
481 break;
486 // <--
488 if ( !bAnchoredObjs )
489 DelLastNode();
492 else if (0 != (pAktNd = pDoc->GetNodes()[nNodeIdx]->GetTxtNode()))
494 if( pAktNd->CanJoinNext( &pPos->nNode ))
496 SwTxtNode* pNextNd = pPos->nNode.GetNode().GetTxtNode();
497 pPos->nContent.Assign( pNextNd, 0 );
498 pPam->SetMark(); pPam->DeleteMark();
499 pNextNd->JoinPrev();
501 else if( !pAktNd->GetTxt().Len() &&
502 pAktNd->StartOfSectionIndex()+2 <
503 pAktNd->EndOfSectionIndex() )
505 pPos->nContent.Assign( 0, 0 );
506 pPam->SetMark(); pPam->DeleteMark();
507 pDoc->GetNodes().Delete( pPos->nNode, 1 );
508 pPam->Move( fnMoveBackward );
512 // nun noch das SplitNode vom Ende aufheben
513 else if( !IsNewDoc() )
515 if( pPos->nContent.GetIndex() ) // dann gabs am Ende kein \par,
516 pPam->Move( fnMoveForward, fnGoNode ); // als zum naechsten Node
517 SwTxtNode* pTxtNode = pPos->nNode.GetNode().GetTxtNode();
518 SwNodeIndex aPrvIdx( pPos->nNode );
519 if( pTxtNode && pTxtNode->CanJoinPrev( &aPrvIdx ) &&
520 *pSttNdIdx <= aPrvIdx )
522 // eigentlich muss hier ein JoinNext erfolgen, aber alle Cursor
523 // usw. sind im pTxtNode angemeldet, so dass der bestehen
524 // bleiben MUSS.
526 // Absatz in Zeichen-Attribute umwandeln, aus dem Prev die
527 // Absatzattribute und die Vorlage uebernehmen!
528 SwTxtNode* pPrev = aPrvIdx.GetNode().GetTxtNode();
529 pTxtNode->ChgFmtColl( pPrev->GetTxtColl() );
530 pTxtNode->FmtToTxtAttr( pPrev );
531 pTxtNode->ResetAllAttr();
533 if( pPrev->HasSwAttrSet() )
534 pTxtNode->SetAttr( *pPrev->GetpSwAttrSet() );
536 if( &pPam->GetBound(TRUE).nNode.GetNode() == pPrev )
537 pPam->GetBound(TRUE).nContent.Assign( pTxtNode, 0 );
538 if( &pPam->GetBound(FALSE).nNode.GetNode() == pPrev )
539 pPam->GetBound(FALSE).nContent.Assign( pTxtNode, 0 );
541 pTxtNode->JoinPrev();
545 delete pSttNdIdx, pSttNdIdx = 0;
546 delete pRegionEndIdx, pRegionEndIdx = 0;
547 RemoveUnusedNumRules();
549 pDoc->SetUpdateExpFldStat(true);
550 pDoc->SetInitDBFields(true);
552 // Laufbalken bei asynchronen Call nicht einschalten !!!
553 ::EndProgress( pDoc->GetDocShell() );
556 bool rtfSections::SetCols(SwFrmFmt &rFmt, const rtfSection &rSection,
557 USHORT nNettoWidth)
559 //sprmSCcolumns - Anzahl der Spalten - 1
560 USHORT nCols = static_cast< USHORT >(rSection.NoCols());
562 if (nCols < 2)
563 return false; // keine oder bloedsinnige Spalten
565 SwFmtCol aCol; // Erzeuge SwFmtCol
567 //sprmSDxaColumns - Default-Abstand 1.25 cm
568 USHORT nColSpace = static_cast< USHORT >(rSection.StandardColSeperation());
570 aCol.Init( nCols, nColSpace, nNettoWidth );
572 // not SFEvenlySpaced
573 if (rSection.maPageInfo.maColumns.size())
575 aCol._SetOrtho(false);
576 USHORT nWishWidth = 0, nHalfPrev = 0;
577 for(USHORT n=0, i=0; n < rSection.maPageInfo.maColumns.size() && i < nCols; n += 2, ++i )
579 SwColumn* pCol = aCol.GetColumns()[ i ];
580 pCol->SetLeft( nHalfPrev );
581 USHORT nSp = static_cast< USHORT >(rSection.maPageInfo.maColumns[ n+1 ]);
582 nHalfPrev = nSp / 2;
583 pCol->SetRight( nSp - nHalfPrev );
584 pCol->SetWishWidth( static_cast< USHORT >(rSection.maPageInfo.maColumns[ n ]) +
585 pCol->GetLeft() + pCol->GetRight());
586 nWishWidth = nWishWidth + pCol->GetWishWidth();
588 aCol.SetWishWidth( nWishWidth );
591 rFmt.SetFmtAttr(aCol);
592 return true;
595 void rtfSections::SetPage(SwPageDesc &rInPageDesc, SwFrmFmt &rFmt,
596 const rtfSection &rSection, bool bIgnoreCols)
598 // 1. Orientierung
599 rInPageDesc.SetLandscape(rSection.IsLandScape());
601 // 2. Papiergroesse
602 SwFmtFrmSize aSz(rFmt.GetFrmSize());
603 aSz.SetWidth(rSection.GetPageWidth());
604 aSz.SetHeight(rSection.GetPageHeight());
605 rFmt.SetFmtAttr(aSz);
607 rFmt.SetFmtAttr(
608 SvxLRSpaceItem(rSection.GetPageLeft(), rSection.GetPageRight(), 0, 0, RES_LR_SPACE));
610 if (!bIgnoreCols)
612 SetCols(rFmt, rSection, static_cast< USHORT >(rSection.GetPageWidth() -
613 rSection.GetPageLeft() - rSection.GetPageRight()));
616 rFmt.SetFmtAttr(rSection.maPageInfo.maBox);
619 bool HasHeader(const SwFrmFmt &rFmt)
621 const SfxPoolItem *pHd;
622 if (SFX_ITEM_SET == rFmt.GetItemState(RES_HEADER, false, &pHd))
623 return ((const SwFmtHeader *)(pHd))->IsActive();
624 return false;
627 bool HasFooter(const SwFrmFmt &rFmt)
629 const SfxPoolItem *pFt;
630 if (SFX_ITEM_SET == rFmt.GetItemState(RES_FOOTER, false, &pFt))
631 return ((const SwFmtFooter *)(pFt))->IsActive();
632 return false;
635 void rtfSections::GetPageULData(const rtfSection &rSection, bool bFirst,
636 rtfSections::wwULSpaceData& rData)
638 short nWWUp = static_cast< short >(rSection.maPageInfo.mnMargtsxn);
639 short nWWLo = static_cast< short >(rSection.maPageInfo.mnMargbsxn);
640 short nWWHTop = static_cast< short >(rSection.maPageInfo.mnHeadery);
641 short nWWFBot = static_cast< short >(rSection.maPageInfo.mnFootery);
643 if (bFirst)
645 if (
646 rSection.mpTitlePage && HasHeader(rSection.mpTitlePage->GetMaster())
649 rData.bHasHeader = true;
652 else
654 if (rSection.mpPage &&
656 HasHeader(rSection.mpPage->GetMaster())
657 || HasHeader(rSection.mpPage->GetLeft())
661 rData.bHasHeader = true;
665 if( rData.bHasHeader )
667 rData.nSwUp = nWWHTop; // Header -> umrechnen, see ww8par6.cxx
669 if ( nWWUp > 0 && nWWUp >= nWWHTop )
670 rData.nSwHLo = nWWUp - nWWHTop;
671 else
672 rData.nSwHLo = 0;
674 if (rData.nSwHLo < cMinHdFtHeight)
675 rData.nSwHLo = cMinHdFtHeight;
677 else // kein Header -> Up einfach uebernehmen
678 rData.nSwUp = Abs(nWWUp);
680 if (bFirst)
682 if (
683 rSection.mpTitlePage &&
684 HasFooter(rSection.mpTitlePage->GetMaster())
687 rData.bHasFooter = true;
690 else
692 if (rSection.mpPage &&
694 HasFooter(rSection.mpPage->GetMaster())
695 || HasFooter(rSection.mpPage->GetLeft())
699 rData.bHasFooter = true;
703 if( rData.bHasFooter )
705 rData.nSwLo = nWWFBot; // Footer -> Umrechnen
706 if ( nWWLo > 0 && nWWLo >= nWWFBot )
707 rData.nSwFUp = nWWLo - nWWFBot;
708 else
709 rData.nSwFUp = 0;
711 if (rData.nSwFUp < cMinHdFtHeight)
712 rData.nSwFUp = cMinHdFtHeight;
714 else // kein Footer -> Lo einfach uebernehmen
715 rData.nSwLo = Abs(nWWLo);
718 void rtfSections::SetPageULSpaceItems(SwFrmFmt &rFmt,
719 rtfSections::wwULSpaceData& rData)
721 if (rData.bHasHeader) // ... und Header-Lower setzen
723 //Kopfzeilenhoehe minimal sezten
724 if (SwFrmFmt* pHdFmt = (SwFrmFmt*)rFmt.GetHeader().GetHeaderFmt())
726 pHdFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwHLo));
727 SvxULSpaceItem aHdUL(pHdFmt->GetULSpace());
728 aHdUL.SetLower( rData.nSwHLo - cMinHdFtHeight );
729 pHdFmt->SetFmtAttr(aHdUL);
730 pHdFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
731 RES_HEADER_FOOTER_EAT_SPACING, true));
735 if (rData.bHasFooter) // ... und Footer-Upper setzen
737 if (SwFrmFmt* pFtFmt = (SwFrmFmt*)rFmt.GetFooter().GetFooterFmt())
739 pFtFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwFUp));
740 SvxULSpaceItem aFtUL(pFtFmt->GetULSpace());
741 aFtUL.SetUpper( rData.nSwFUp - cMinHdFtHeight );
742 pFtFmt->SetFmtAttr(aFtUL);
743 pFtFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
744 RES_HEADER_FOOTER_EAT_SPACING, true));
748 SvxULSpaceItem aUL(rData.nSwUp, rData.nSwLo, RES_UL_SPACE ); // Page-UL setzen
749 rFmt.SetFmtAttr(aUL);
752 void rtfSections::SetSegmentToPageDesc(const rtfSection &rSection,
753 bool bTitlePage, bool bIgnoreCols)
755 SwPageDesc &rPage = bTitlePage ? *rSection.mpTitlePage : *rSection.mpPage;
757 // SetNumberingType(rSection, rPage);
759 SwFrmFmt &rFmt = rPage.GetMaster();
760 // mrReader.SetDocumentGrid(rFmt, rSection);
762 wwULSpaceData aULData;
763 GetPageULData(rSection, bTitlePage, aULData);
764 SetPageULSpaceItems(rFmt, aULData);
766 SetPage(rPage, rFmt, rSection, bIgnoreCols);
768 UseOnPage ePage = rPage.ReadUseOn();
769 if(ePage & nsUseOnPage::PD_ALL)
771 SwFrmFmt &rFmtLeft = rPage.GetLeft();
772 SetPageULSpaceItems(rFmtLeft, aULData);
773 SetPage(rPage, rFmtLeft, rSection, bIgnoreCols);
778 void rtfSections::CopyFrom(const SwPageDesc &rFrom, SwPageDesc &rDest)
780 UseOnPage ePage = rFrom.ReadUseOn();
781 rDest.WriteUseOn(ePage);
783 mrReader.pDoc->CopyHeader(rFrom.GetMaster(), rDest.GetMaster());
784 SwFrmFmt &rDestFmt = rDest.GetMaster();
785 rDestFmt.SetFmtAttr(rFrom.GetMaster().GetHeader());
786 mrReader.pDoc->CopyHeader(rFrom.GetLeft(), rDest.GetLeft());
787 mrReader.pDoc->CopyFooter(rFrom.GetMaster(), rDest.GetMaster());
788 mrReader.pDoc->CopyFooter(rFrom.GetLeft(), rDest.GetLeft());
791 void rtfSections::MoveFrom(SwPageDesc &rFrom, SwPageDesc &rDest)
793 UseOnPage ePage = rFrom.ReadUseOn();
794 rDest.WriteUseOn(ePage);
796 SwFrmFmt &rDestMaster = rDest.GetMaster();
797 SwFrmFmt &rFromMaster = rFrom.GetMaster();
798 rDestMaster.SetFmtAttr(rFromMaster.GetHeader());
799 rDestMaster.SetFmtAttr(rFromMaster.GetFooter());
800 //rFromMaster.SetAttr(SwFmtHeader()); //$flr uncommented due to bug fix #117882#
801 //rFromMaster.SetAttr(SwFmtFooter()); //$flr uncommented due to bug fix #117882#
803 SwFrmFmt &rDestLeft = rDest.GetLeft();
804 SwFrmFmt &rFromLeft = rFrom.GetLeft();
805 rDestLeft.SetFmtAttr(rFromLeft.GetHeader());
806 rDestLeft.SetFmtAttr(rFromLeft.GetFooter());
807 //rFromLeft.SetAttr(SwFmtHeader()); //$flr uncommented due to bug fix #117882#
808 //rFromLeft.SetAttr(SwFmtFooter()); //$flr uncommented due to bug fix #117882#
811 void rtfSections::SetHdFt(rtfSection &rSection)
813 ASSERT(rSection.mpPage, "makes no sense to call without a main page");
814 if (rSection.mpPage && rSection.maPageInfo.mpPageHdFt)
816 if (rSection.maPageInfo.mbPageHdFtUsed)
818 MoveFrom(*rSection.maPageInfo.mpPageHdFt, *rSection.mpPage);
819 rSection.maPageInfo.mbPageHdFtUsed = false;
820 rSection.maPageInfo.mpPageHdFt = rSection.mpPage;
822 else
823 CopyFrom(*rSection.maPageInfo.mpPageHdFt, *rSection.mpPage);
826 if (rSection.mpTitlePage && rSection.maPageInfo.mpTitlePageHdFt)
828 if (rSection.maPageInfo.mbTitlePageHdFtUsed)
830 MoveFrom(*rSection.maPageInfo.mpTitlePageHdFt,
831 *rSection.mpTitlePage);
832 rSection.maPageInfo.mbTitlePageHdFtUsed = false;
833 rSection.maPageInfo.mpTitlePageHdFt = rSection.mpTitlePage;
835 else
837 CopyFrom(*rSection.maPageInfo.mpTitlePageHdFt,
838 *rSection.mpTitlePage);
843 SwSectionFmt *rtfSections::InsertSection(SwPaM& rMyPaM, rtfSection &rSection)
845 SwSection aSection(CONTENT_SECTION, mrReader.pDoc->GetUniqueSectionName());
847 SfxItemSet aSet( mrReader.pDoc->GetAttrPool(), aFrmFmtSetRange );
849 sal_uInt8 nRTLPgn = maSegments.empty() ? 0 : maSegments.back().IsBiDi();
850 aSet.Put(SvxFrameDirectionItem(
851 nRTLPgn ? FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR));
853 rSection.mpSection =
854 mrReader.pDoc->InsertSwSection( rMyPaM, aSection, &aSet );
855 ASSERT(rSection.mpSection, "section not inserted!");
856 if (!rSection.mpSection)
857 return 0;
859 SwPageDesc *pPage = 0;
860 mySegrIter aEnd = maSegments.rend();
861 for (mySegrIter aIter = maSegments.rbegin(); aIter != aEnd; ++aIter)
863 pPage = aIter->mpPage;
864 if (pPage)
865 break;
868 ASSERT(pPage, "no page outside this section!");
870 if (!pPage)
871 pPage = &mrReader.pDoc->_GetPageDesc(0);
873 if (!pPage)
874 return 0;
876 SwFrmFmt& rFmt = pPage->GetMaster();
877 const SwFmtFrmSize& rSz = rFmt.GetFrmSize();
878 const SvxLRSpaceItem& rLR = rFmt.GetLRSpace();
879 SwTwips nWidth = rSz.GetWidth();
880 long nLeft = rLR.GetTxtLeft();
881 long nRight = rLR.GetRight();
883 SwSectionFmt *pFmt = rSection.mpSection->GetFmt();
884 ASSERT(pFmt, "impossible");
885 if (!pFmt)
886 return 0;
887 SetCols(*pFmt, rSection, (USHORT)(nWidth - nLeft - nRight) );
889 return pFmt;
892 void rtfSections::InsertSegments(bool bNewDoc)
894 sal_uInt16 nDesc(0);
895 mySegIter aEnd = maSegments.end();
896 mySegIter aStart = maSegments.begin();
897 for (mySegIter aIter = aStart; aIter != aEnd; ++aIter)
899 mySegIter aNext = aIter+1;
901 bool bInsertSection = aIter != aStart ? aIter->IsContinous() : false;
903 if (!bInsertSection)
906 If a cont section follow this section then we won't be
907 creating a page desc with 2+ cols as we cannot host a one
908 col section in a 2+ col pagedesc and make it look like
909 word. But if the current section actually has columns then
910 we are forced to insert a section here as well as a page
911 descriptor.
915 Note for the future:
916 If we want to import "protected sections" the here is
917 where we would also test for that and force a section
918 insertion if that was true.
920 bool bIgnoreCols = false;
921 if (aNext != aEnd && aNext->IsContinous())
923 bIgnoreCols = true;
924 if (aIter->NoCols() > 1)
925 bInsertSection = true;
928 if (aIter->HasTitlePage())
930 if (bNewDoc && aIter == aStart)
932 aIter->mpTitlePage =
933 mrReader.pDoc->GetPageDescFromPool(RES_POOLPAGE_FIRST);
935 else
937 USHORT nPos = mrReader.pDoc->MakePageDesc(
938 ViewShell::GetShellRes()->GetPageDescName(nDesc)
939 , 0, false);
940 aIter->mpTitlePage = &mrReader.pDoc->_GetPageDesc(nPos);
942 ASSERT(aIter->mpTitlePage, "no page!");
943 if (!aIter->mpTitlePage)
944 continue;
946 SetSegmentToPageDesc(*aIter, true, bIgnoreCols);
949 if (!bNewDoc && aIter == aStart)
950 continue;
951 else if (bNewDoc && aIter == aStart)
953 aIter->mpPage =
954 mrReader.pDoc->GetPageDescFromPool(RES_POOLPAGE_STANDARD);
956 else
958 USHORT nPos = mrReader.pDoc->MakePageDesc(
959 ViewShell::GetShellRes()->GetPageDescName(nDesc,
960 false, aIter->HasTitlePage()),
961 aIter->mpTitlePage, false);
962 aIter->mpPage = &mrReader.pDoc->_GetPageDesc(nPos);
964 ASSERT(aIter->mpPage, "no page!");
965 if (!aIter->mpPage)
966 continue;
968 SetHdFt(*aIter);
970 if (aIter->mpTitlePage)
971 SetSegmentToPageDesc(*aIter, true, bIgnoreCols);
972 SetSegmentToPageDesc(*aIter, false, bIgnoreCols);
974 SwFmtPageDesc aPgDesc(aIter->HasTitlePage() ?
975 aIter->mpTitlePage : aIter->mpPage);
977 if (aIter->mpTitlePage)
978 aIter->mpTitlePage->SetFollow(aIter->mpPage);
980 if (aIter->PageRestartNo() ||
981 ((aIter == aStart) && aIter->PageStartAt() != 1))
982 aPgDesc.SetNumOffset( static_cast< USHORT >(aIter->PageStartAt()) );
985 If its a table here, apply the pagebreak to the table
986 properties, otherwise we add it to the para at this
987 position
989 if (aIter->maStart.GetNode().IsTableNode())
991 SwTable& rTable =
992 aIter->maStart.GetNode().GetTableNode()->GetTable();
993 SwFrmFmt* pApply = rTable.GetFrmFmt();
994 ASSERT(pApply, "impossible");
995 if (pApply)
996 pApply->SetFmtAttr(aPgDesc);
998 else
1000 SwPosition aPamStart(aIter->maStart);
1001 aPamStart.nContent.Assign(
1002 aIter->maStart.GetNode().GetCntntNode(), 0);
1003 SwPaM aPage(aPamStart);
1005 mrReader.pDoc->InsertPoolItem(aPage, aPgDesc, 0);
1007 ++nDesc;
1010 SwTxtNode* pTxtNd = 0;
1011 if (bInsertSection)
1013 SwPaM aSectPaM(*mrReader.pPam);
1014 SwNodeIndex aAnchor(aSectPaM.GetPoint()->nNode);
1015 if (aNext != aEnd)
1017 aAnchor = aNext->maStart;
1018 aSectPaM.GetPoint()->nNode = aAnchor;
1019 aSectPaM.GetPoint()->nContent.Assign(
1020 aNext->maStart.GetNode().GetCntntNode(), 0);
1021 aSectPaM.Move(fnMoveBackward);
1024 const SwPosition* pPos = aSectPaM.GetPoint();
1025 const SwTxtNode* pSttNd =
1026 mrReader.pDoc->GetNodes()[ pPos->nNode ]->GetTxtNode();
1027 const SwTableNode* pTableNd = pSttNd ? pSttNd->FindTableNode() : 0;
1028 if (pTableNd)
1030 pTxtNd =
1031 mrReader.pDoc->GetNodes().MakeTxtNode(aAnchor,
1032 mrReader.pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT ));
1034 aSectPaM.GetPoint()->nNode = SwNodeIndex(*pTxtNd);
1035 aSectPaM.GetPoint()->nContent.Assign(
1036 aSectPaM.GetCntntNode(), 0);
1039 aSectPaM.SetMark();
1041 aSectPaM.GetPoint()->nNode = aIter->maStart;
1042 aSectPaM.GetPoint()->nContent.Assign(
1043 aSectPaM.GetCntntNode(), 0);
1045 SwSectionFmt *pRet = InsertSection(aSectPaM, *aIter);
1046 //The last section if continous is always unbalanced
1047 if (aNext == aEnd && pRet)
1048 pRet->SetFmtAttr(SwFmtNoBalancedColumns(true));
1051 if (pTxtNd)
1053 SwNodeIndex aIdx(*pTxtNd);
1054 SwPosition aPos(aIdx);
1055 SwPaM aTest(aPos);
1056 mrReader.pDoc->DelFullPara(aTest);
1057 pTxtNd = 0;
1062 namespace sw{
1063 namespace util{
1065 InsertedTableClient::InsertedTableClient(SwTableNode & rNode)
1067 rNode.Add(this);
1070 SwTableNode * InsertedTableClient::GetTableNode()
1072 return dynamic_cast<SwTableNode *> (pRegisteredIn);
1075 InsertedTablesManager::InsertedTablesManager(const SwDoc &rDoc)
1076 : mbHasRoot(rDoc.GetRootFrm())
1080 void InsertedTablesManager::DelAndMakeTblFrms()
1082 if (!mbHasRoot)
1083 return;
1084 TblMapIter aEnd = maTables.end();
1085 for (TblMapIter aIter = maTables.begin(); aIter != aEnd; ++aIter)
1087 // exitiert schon ein Layout, dann muss an dieser Tabelle die BoxFrames
1088 // neu erzeugt
1089 SwTableNode *pTable = aIter->first->GetTableNode();
1090 ASSERT(pTable, "Why no expected table");
1091 if (pTable)
1093 SwFrmFmt * pFrmFmt = pTable->GetTable().GetFrmFmt();
1095 if (pFrmFmt != NULL)
1097 SwNodeIndex *pIndex = aIter->second;
1098 pTable->DelFrms();
1099 pTable->MakeFrms(pIndex);
1105 void InsertedTablesManager::InsertTable(SwTableNode &rTableNode, SwPaM &rPaM)
1107 if (!mbHasRoot)
1108 return;
1109 //Associate this tablenode with this after position, replace an //old
1110 //node association if necessary
1112 InsertedTableClient * pClient = new InsertedTableClient(rTableNode);
1114 maTables.insert(TblMap::value_type(pClient, &(rPaM.GetPoint()->nNode)));
1119 SwRTFParser::~SwRTFParser()
1121 maInsertedTables.DelAndMakeTblFrms();
1122 mpRedlineStack->closeall(*pPam->GetPoint());
1123 delete mpRedlineStack;
1125 delete pSttNdIdx;
1126 delete pRegionEndIdx;
1127 delete pPam;
1128 delete pRelNumRule;
1130 if (aFlyArr.Count())
1131 aFlyArr.DeleteAndDestroy( 0, aFlyArr.Count() );
1133 if (pGrfAttrSet)
1134 DELETEZ( pGrfAttrSet );
1136 DELETEZ( pAuthorInfos );
1139 //i19718
1140 void SwRTFParser::ReadShpRslt()
1142 int nToken;
1143 while ('}' != (nToken = GetNextToken() ) && IsParserWorking())
1145 switch(nToken)
1147 case RTF_PAR:
1148 break;
1149 default:
1150 NextToken(nToken);
1151 break;
1154 SkipToken(-1);
1157 void SwRTFParser::ReadShpTxt(String& s)
1159 int nToken;
1160 int level=1;
1161 s.AppendAscii("{\\rtf");
1162 while (level>0 && IsParserWorking())
1164 nToken = GetNextToken();
1165 switch(nToken)
1167 case RTF_SN:
1168 case RTF_SV:
1169 SkipGroup();
1170 break;
1171 case RTF_TEXTTOKEN:
1172 s.Append(aToken);
1173 break;
1174 case '{':
1175 level++;
1176 s.Append(String::CreateFromAscii("{"));
1177 break;
1178 case '}':
1179 level--;
1180 s.Append(String::CreateFromAscii("}"));
1181 break;
1182 default:
1183 s.Append(aToken);
1184 if (bTokenHasValue) {
1185 s.Append(String::CreateFromInt64(nTokenValue));
1187 s.Append(String::CreateFromAscii(" "));
1188 break;
1191 SkipToken(-1);
1195 * #127429#. Very basic support for the "Buchhalternase".
1197 void SwRTFParser::ReadDrawingObject()
1199 int nToken;
1200 int level;
1201 level=1;
1202 Rectangle aRect;
1203 ::basegfx::B2DPolygon aPolygon;
1204 ::basegfx::B2DPoint aPoint;
1205 bool bPolygonActive(false);
1207 while (level>0 && IsParserWorking())
1209 nToken = GetNextToken();
1210 switch(nToken)
1212 case '}':
1213 level--;
1214 break;
1215 case '{':
1216 level++;
1217 break;
1218 case RTF_DPX:
1219 aRect.setX(nTokenValue);
1220 break;
1221 case RTF_DPXSIZE:
1222 aRect.setWidth(nTokenValue);
1223 break;
1224 case RTF_DPY:
1225 aRect.setY(nTokenValue);
1226 break;
1227 case RTF_DPYSIZE:
1228 aRect.setHeight(nTokenValue);
1229 break;
1230 case RTF_DPPOLYCOUNT:
1231 bPolygonActive = true;
1232 break;
1233 case RTF_DPPTX:
1234 aPoint.setX(nTokenValue);
1235 break;
1236 case RTF_DPPTY:
1237 aPoint.setY(nTokenValue);
1239 if(bPolygonActive)
1241 aPolygon.append(aPoint);
1244 break;
1245 default:
1246 break;
1249 SkipToken(-1);
1251 const Point aPointC1( 0, 0 );
1252 const Point aPointC2( 100, 200 );
1253 const Point aPointC3( 300, 400 );
1254 XPolygon aPolygonC(3);
1255 aPolygonC[0] = aPointC1;
1256 aPolygonC[1] = aPointC2;
1257 aPolygonC[2] = aPointC3;
1259 if(bPolygonActive && aPolygon.count())
1261 SdrPathObj* pStroke = new SdrPathObj(OBJ_PLIN, ::basegfx::B2DPolyPolygon(aPolygon));
1262 SfxItemSet aFlySet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1);
1263 SwFmtSurround aSur( SURROUND_PARALLEL );
1264 aSur.SetContour( false );
1265 aSur.SetOutside(true);
1266 aFlySet.Put( aSur );
1267 SwFmtFollowTextFlow aFollowTextFlow( FALSE );
1268 aFlySet.Put( aFollowTextFlow );
1270 sw::util::SetLayer aSetLayer(*pDoc);
1271 aSetLayer.SendObjectToHeaven(*pStroke);
1274 FLY_AT_CNTNT, //Absatzgebundener Rahmen <to paragraph>
1275 FLY_IN_CNTNT, //Zeichengebundener Rahmen <as character>
1276 FLY_PAGE, //Seitengebundener Rahmen <to page>
1277 FLY_AT_FLY, //Rahmengebundener Rahmen ( LAYER_IMPL ) <to frame>
1278 FLY_AUTO_CNTNT, //Automatisch positionierter, absatzgebundener Rahmen <to character>
1280 SwFmtAnchor aAnchor( FLY_AT_CNTNT );
1281 aAnchor.SetAnchor( pPam->GetPoint() );
1282 aFlySet.Put( aAnchor );
1285 text::RelOrientation::FRAME, // Absatz inkl. Raender
1286 text::RelOrientation::PRINT_AREA, // Absatz ohne Raender
1287 text::RelOrientation::CHAR, // an einem Zeichen
1288 text::RelOrientation::PAGE_LEFT, // im linken Seitenrand
1289 text::RelOrientation::PAGE_RIGHT, // im rechten Seitenrand
1290 text::RelOrientation::FRAME_LEFT, // im linken Absatzrand
1291 text::RelOrientation::FRAME_RIGHT, // im rechten Absatzrand
1292 text::RelOrientation::PAGE_FRAME, // Seite inkl. Raender, bei seitengeb. identisch mit text::RelOrientation::FRAME
1293 text::RelOrientation::PAGE_PRINT_AREA, // Seite ohne Raender, bei seitengeb. identisch mit text::RelOrientation::PRTAREA
1294 // OD 11.11.2003 #i22341#
1295 text::RelOrientation::TEXT_LINE, // vertical relative to top of text line, only for to-character
1296 // anchored objects.
1299 text::HoriOrientation::NONE, //Der Wert in nYPos gibt die RelPos direkt an.
1300 text::HoriOrientation::RIGHT, //Der Rest ist fuer automatische Ausrichtung.
1301 text::HoriOrientation::CENTER,
1302 text::HoriOrientation::LEFT,
1303 text::HoriOrientation::INSIDE,
1304 text::HoriOrientation::OUTSIDE,
1305 text::HoriOrientation::FULL, //Spezialwert fuer Tabellen
1306 text::HoriOrientation::LEFT_AND_WIDTH //Auch fuer Tabellen
1308 SwFmtHoriOrient aHori( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME );
1309 aFlySet.Put( aHori );
1311 text::VertOrientation::NONE, //Der Wert in nYPos gibt die RelPos direkt an.
1312 text::VertOrientation::TOP, //Der Rest ist fuer automatische Ausrichtung.
1313 text::VertOrientation::CENTER,
1314 text::VertOrientation::BOTTOM,
1315 text::VertOrientation::CHAR_TOP, //Ausrichtung _nur_ fuer Zeichengebundene Rahmen
1316 text::VertOrientation::CHAR_CENTER, //wie der Name jew. sagt wird der RefPoint des Rahmens
1317 text::VertOrientation::CHAR_BOTTOM, //entsprechend auf die Oberkante, Mitte oder Unterkante
1318 text::VertOrientation::LINE_TOP, //der Zeile gesetzt. Der Rahmen richtet sich dann
1319 text::VertOrientation::LINE_CENTER, //entsprechend aus.
1320 text::VertOrientation::LINE_BOTTOM
1322 SwFmtVertOrient aVert( 0, text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME );
1323 aFlySet.Put( aVert );
1325 pDoc->GetOrCreateDrawModel();
1326 SdrModel* pDrawModel = pDoc->GetDrawModel();
1327 SdrPage* pDrawPg = pDrawModel->GetPage(0);
1328 pDrawPg->InsertObject(pStroke, 0);
1330 pStroke->SetSnapRect(aRect);
1332 /* SwFrmFmt* pRetFrmFmt = */pDoc->Insert(*pPam, *pStroke, &aFlySet, NULL);
1336 void SwRTFParser::InsertShpObject(SdrObject* pStroke, int _nZOrder)
1338 SfxItemSet aFlySet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1);
1339 SwFmtSurround aSur( SURROUND_THROUGHT );
1340 aSur.SetContour( false );
1341 aSur.SetOutside(true);
1342 aFlySet.Put( aSur );
1343 SwFmtFollowTextFlow aFollowTextFlow( FALSE );
1344 aFlySet.Put( aFollowTextFlow );
1346 SwFmtAnchor aAnchor( FLY_AT_CNTNT );
1347 aAnchor.SetAnchor( pPam->GetPoint() );
1348 aFlySet.Put( aAnchor );
1351 SwFmtHoriOrient aHori( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME );
1352 aFlySet.Put( aHori );
1354 SwFmtVertOrient aVert( 0, text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME );
1355 aFlySet.Put( aVert );
1357 aFlySet.Put(SvxOpaqueItem(RES_OPAQUE,false));
1359 pDoc->GetOrCreateDrawModel();
1360 SdrModel* pDrawModel = pDoc->GetDrawModel();
1361 SdrPage* pDrawPg = pDrawModel->GetPage(0);
1362 pDrawPg->InsertObject(pStroke);
1363 pDrawPg->SetObjectOrdNum(pStroke->GetOrdNum(), _nZOrder);
1364 /* SwFrmFmt* pRetFrmFmt = */pDoc->Insert(*pPam, *pStroke, &aFlySet, NULL);
1367 ::basegfx::B2DPoint rotate(const ::basegfx::B2DPoint& rStart, const ::basegfx::B2DPoint& rEnd)
1369 const ::basegfx::B2DVector aVector(rStart - rEnd);
1370 return ::basegfx::B2DPoint(aVector.getY() + rEnd.getX(), -aVector.getX() + rEnd.getY());
1374 void SwRTFParser::ReadShapeObject()
1376 int nToken;
1377 int level;
1378 level=1;
1379 ::basegfx::B2DPoint aPointLeftTop;
1380 ::basegfx::B2DPoint aPointRightBottom;
1381 String sn;
1382 sal_Int32 shapeType=-1;
1383 Graphic aGrf;
1384 bool bGrfValid=false;
1385 bool fFilled=true;
1386 Color fillColor(255, 255, 255);
1387 bool fLine=true;
1388 int lineWidth=9525/360;
1389 String shpTxt;
1390 bool bshpTxt=false;
1391 int txflTextFlow=0;
1394 while (level>0 && IsParserWorking())
1396 nToken = GetNextToken();
1397 switch(nToken)
1399 case '}':
1400 level--;
1401 break;
1402 case '{':
1403 level++;
1404 break;
1405 case RTF_SHPLEFT:
1406 aPointLeftTop.setX(nTokenValue);
1407 break;
1408 case RTF_SHPTOP:
1409 aPointLeftTop.setY(nTokenValue);
1410 break;
1411 case RTF_SHPBOTTOM:
1412 aPointRightBottom.setY(nTokenValue);
1413 break;
1414 case RTF_SHPRIGHT:
1415 aPointRightBottom.setX(nTokenValue);
1416 break;
1417 case RTF_SN:
1418 nToken = GetNextToken();
1419 ASSERT(nToken==RTF_TEXTTOKEN, "expected name");
1420 sn=aToken;
1421 break;
1422 case RTF_SV:
1423 nToken = GetNextToken();
1424 if (nToken==RTF_TEXTTOKEN)
1426 if (sn.EqualsAscii("shapeType"))
1428 shapeType=aToken.ToInt32();
1430 } else if (sn.EqualsAscii("fFilled"))
1432 fFilled=aToken.ToInt32();
1434 } else if (sn.EqualsAscii("fLine"))
1436 fLine=aToken.ToInt32();
1437 } else if (sn.EqualsAscii("lineWidth"))
1439 lineWidth=aToken.ToInt32()/360;
1441 } else if (sn.EqualsAscii("fillColor"))
1443 sal_uInt32 nColor=aToken.ToInt32();
1444 fillColor=Color( (sal_uInt8)nColor, (sal_uInt8)( nColor >> 8 ), (sal_uInt8)( nColor >> 16 ) );
1445 }else if (sn.EqualsAscii("txflTextFlow"))
1447 txflTextFlow=aToken.ToInt32();
1451 break;
1452 case RTF_PICT:
1454 SvxRTFPictureType aPicType;
1455 bGrfValid=ReadBmpData( aGrf, aPicType );
1457 break;
1458 case RTF_SHPRSLT:
1459 if (shapeType!=1 && shapeType!=20 && shapeType!=75)
1461 ReadShpRslt();
1463 break;
1464 case RTF_SHPTXT:
1465 ReadShpTxt(shpTxt);
1466 bshpTxt=true;
1467 break;
1469 default:
1470 break;
1473 SkipToken(-1);
1475 switch(shapeType)
1477 case 202: /* Text Box */
1478 case 1: /* Rectangle */
1480 ::basegfx::B2DRange aRange(aPointLeftTop);
1481 aRange.expand(aPointRightBottom);
1483 if (txflTextFlow==2) {
1484 const ::basegfx::B2DPoint a(rotate(aRange.getMinimum(), aRange.getCenter()));
1485 const ::basegfx::B2DPoint b(rotate(aRange.getMaximum(), aRange.getCenter()));
1487 aRange.reset();
1488 aRange.expand(a);
1489 aRange.expand(b);
1492 const Rectangle aRect(FRound(aRange.getMinX()), FRound(aRange.getMinY()), FRound(aRange.getMaxX()), FRound(aRange.getMaxY()));
1493 SdrRectObj* pStroke = new SdrRectObj(aRect);
1494 pStroke->SetSnapRect(aRect);
1495 pDoc->GetOrCreateDrawModel(); // create model
1496 InsertShpObject(pStroke, this->nZOrder++);
1497 SfxItemSet aSet(pStroke->GetMergedItemSet());
1498 if (fFilled)
1500 aSet.Put(XFillStyleItem(XFILL_SOLID));
1501 aSet.Put(XFillColorItem( String(), fillColor ) );
1503 else
1505 aSet.Put(XFillStyleItem(XFILL_NONE));
1507 if (!fLine) {
1508 aSet.Put(XLineStyleItem(XLINE_NONE));
1509 } else {
1510 aSet.Put( XLineWidthItem( lineWidth/2 ) ); // lineWidth are in 1000th mm, seems that XLineWidthItem expects 1/2 the line width
1513 pStroke->SetMergedItemSet(aSet);
1514 if (bshpTxt) {
1515 SdrOutliner& rOutliner=pDoc->GetDrawModel()->GetDrawOutliner(pStroke);
1516 rOutliner.Clear();
1517 ByteString bs(shpTxt, RTL_TEXTENCODING_ASCII_US);
1518 SvMemoryStream aStream((sal_Char*)bs.GetBuffer(), bs.Len(), STREAM_READ);
1519 rOutliner.Read(aStream, String::CreateFromAscii(""), EE_FORMAT_RTF);
1520 OutlinerParaObject* pParaObject=rOutliner.CreateParaObject();
1521 pStroke->NbcSetOutlinerParaObject(pParaObject);
1522 //delete pParaObject;
1523 rOutliner.Clear();
1525 if (txflTextFlow==2) {
1526 long nAngle = 90;
1527 double a = nAngle*100*nPi180;
1528 pStroke->Rotate(pStroke->GetCurrentBoundRect().Center(), nAngle*100, sin(a), cos(a) );
1533 break;
1534 case 20: /* Line */
1536 ::basegfx::B2DPolygon aLine;
1537 aLine.append(aPointLeftTop);
1538 aLine.append(aPointRightBottom);
1540 SdrPathObj* pStroke = new SdrPathObj(OBJ_PLIN, ::basegfx::B2DPolyPolygon(aLine));
1541 //pStroke->SetSnapRect(aRect);
1543 InsertShpObject(pStroke, this->nZOrder++);
1544 SfxItemSet aSet(pStroke->GetMergedItemSet());
1545 if (!fLine) {
1546 aSet.Put(XLineStyleItem(XLINE_NONE));
1547 } else {
1548 aSet.Put( XLineWidthItem( lineWidth/2 ) ); // lineWidth are in 1000th mm, seems that XLineWidthItem expects 1/2 the line width
1551 pStroke->SetMergedItemSet(aSet);
1553 break;
1554 case 75 : /* Picture */
1555 if (bGrfValid) {
1556 ::basegfx::B2DRange aRange(aPointLeftTop);
1557 aRange.expand(aPointRightBottom);
1558 const Rectangle aRect(FRound(aRange.getMinX()), FRound(aRange.getMinY()), FRound(aRange.getMaxX()), FRound(aRange.getMaxY()));
1560 SdrRectObj* pStroke = new SdrGrafObj(aGrf);
1561 pStroke->SetSnapRect(aRect);
1563 InsertShpObject(pStroke, this->nZOrder++);
1568 extern void sw3io_ConvertFromOldField( SwDoc& rDoc, USHORT& rWhich,
1569 USHORT& rSubType, ULONG &rFmt,
1570 USHORT nVersion );
1572 USHORT SwRTFParser::ReadRevTbl()
1574 // rStr.Erase( 0 );
1575 int nNumOpenBrakets = 1, nToken; // die erste wurde schon vorher erkannt !!
1576 USHORT nAuthorTableIndex = 0;
1578 while( nNumOpenBrakets && IsParserWorking() )
1580 switch( nToken = GetNextToken() )
1582 case '}': --nNumOpenBrakets; break;
1583 case '{':
1585 if( RTF_IGNOREFLAG != GetNextToken() )
1586 nToken = SkipToken( -1 );
1587 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
1588 nToken = SkipToken( -2 );
1589 else
1591 ReadUnknownData();
1592 nToken = GetNextToken();
1593 if( '}' != nToken )
1594 eState = SVPAR_ERROR;
1595 break;
1597 ++nNumOpenBrakets;
1599 break;
1601 case RTF_TEXTTOKEN:
1602 aToken.EraseTrailingChars(';');
1604 USHORT nSWId = pDoc->InsertRedlineAuthor(aToken);
1605 // Store matchpair
1606 if( !pAuthorInfos )
1607 pAuthorInfos = new sw::util::AuthorInfos;
1608 sw::util::AuthorInfo* pAutorInfo = new sw::util::AuthorInfo( nAuthorTableIndex, nSWId );
1609 if( 0 == pAuthorInfos->Insert( pAutorInfo ) )
1610 delete pAutorInfo;
1612 aRevTbl.push_back(aToken);
1613 nAuthorTableIndex++;
1614 break;
1617 SkipToken( -1 );
1618 return nAuthorTableIndex;
1621 // #117910# simulate words behaviour of \keepn in table rows
1622 void fixKeepAndSplitAttributes(SwTableNode *pTableNode)
1624 ASSERT(pTableNode!=NULL, "no table node!");
1625 if (!pTableNode) return;
1626 SwDoc *pDoc=pTableNode->GetDoc();
1627 if (pTableNode==NULL) return;
1628 SwTable& rTable=pTableNode->GetTable();
1629 SwTableLines& rLns = rTable.GetTabLines();
1630 USHORT nLines=rLns.Count();
1631 if (nLines==0) return;
1632 // get first paragaph in left down-most box
1633 SwTableLine* pLastLine = rLns[ nLines-1 ];
1634 SwTableBox* pBox = pLastLine->GetTabBoxes()[ 0 ];
1635 ULONG iFirstParagraph=pBox->GetSttIdx()+1;
1636 SwTxtNode *pTxtNode=(SwTxtNode *)pDoc->GetNodes()[iFirstParagraph];
1637 SwFrmFmt* pFmt=rTable.GetFrmFmt();
1639 SwFmtLayoutSplit *pTableSplit=(SwFmtLayoutSplit *)pFmt->GetAttrSet().GetItem(RES_LAYOUT_SPLIT);
1640 BOOL isTableKeep = pTableSplit!=NULL && !pTableSplit->GetValue();
1641 SvxFmtKeepItem *pTableKeep=(SvxFmtKeepItem *)pFmt->GetAttrSet().GetItem(RES_KEEP);
1642 BOOL isTableKeepNext = pTableKeep!=NULL && pTableKeep->GetValue();
1643 SvxFmtKeepItem *pKeepNext = (SvxFmtKeepItem *)pTxtNode->GetSwAttrSet().GetItem(RES_KEEP);
1645 if (isTableKeepNext)
1647 if (nLines>2 && !isTableKeep)
1648 { // split
1649 SwTableLine* pSplitLine = rLns[ nLines-2 ];
1650 SwTableBox* pSplitBox = pSplitLine->GetTabBoxes()[ 0 ];
1651 SwNodeIndex aSplitIdx( *pSplitBox->GetSttNd() );
1652 pDoc->SplitTable( SwPosition(aSplitIdx), HEADLINE_NONE,
1653 !isTableKeep );
1654 SwTable& rSplitTable=aSplitIdx.GetNode().FindTableNode()->GetTable();
1655 aSplitIdx-=2;
1656 pDoc->GetNodes().Delete(aSplitIdx);
1657 pFmt=rSplitTable.GetFrmFmt();
1658 pFmt->ResetFmtAttr(RES_PAGEDESC);
1660 // set keep=1(i.e. split=0) attribut
1661 SwFmtLayoutSplit aSplit(0);
1662 SwAttrSet aNewSet(pFmt->GetAttrSet());
1663 aNewSet.Put(aSplit);
1664 pFmt->SetFmtAttr(aNewSet);
1666 else // !isTableKeepNext
1668 if (isTableKeep)
1670 SwNodeIndex aTmpIdx( *pBox->GetSttNd() );
1671 pDoc->SplitTable( SwPosition(aTmpIdx), HEADLINE_NONE, FALSE );
1672 SwTable& rSplitTable=aTmpIdx.GetNode().FindTableNode()->GetTable();
1673 aTmpIdx-=2;
1674 pDoc->GetNodes().Delete(aTmpIdx);
1675 pFmt=rSplitTable.GetFrmFmt();
1676 pFmt->ResetFmtAttr(RES_PAGEDESC);
1678 // set keep=0(i.e. split=1) attribut
1679 SwFmtLayoutSplit aSplit(1);
1680 SwAttrSet aNewSet(pFmt->GetAttrSet());
1681 aNewSet.Put(aSplit);
1682 pFmt->SetFmtAttr(aNewSet);
1684 // move keepnext attribtue from last paragraph to table
1685 if (pKeepNext!=NULL)
1687 SvxFmtKeepItem aNewKeepItem(pKeepNext->GetValue(), RES_KEEP);
1688 SwAttrSet aNewSet(pFmt->GetAttrSet());
1689 aNewSet.Put(aNewKeepItem);
1690 pFmt->SetFmtAttr(aNewSet);
1694 void SwRTFParser::NextToken( int nToken )
1696 USHORT eDateFmt;
1698 switch( nToken )
1700 case RTF_FOOTNOTE:
1701 //We can only insert a footnote if we're not inside a footnote. e.g.
1702 //#i7713#
1703 if (!mbIsFootnote)
1705 ReadHeaderFooter( nToken );
1706 SkipToken( -1 ); // Klammer wieder zurueck
1708 break;
1709 case RTF_SWG_PRTDATA:
1710 ReadPrtData();
1711 break;
1712 case RTF_XE:
1713 ReadXEField();
1714 break;
1715 case RTF_FIELD:
1716 ReadField();
1717 break;
1718 case RTF_SHPRSLT:
1719 ReadShpRslt();
1720 break;
1721 case RTF_DO:
1722 ReadDrawingObject();
1723 break;
1724 case RTF_SHP:
1725 ReadShapeObject();
1726 break;
1727 case RTF_SHPPICT:
1728 case RTF_PICT:
1729 ReadBitmapData();
1730 break;
1731 #ifdef READ_OLE_OBJECT
1732 case RTF_OBJECT:
1733 ReadOLEData();
1734 break;
1735 #endif
1736 case RTF_TROWD: ReadTable( nToken ); break;
1737 case RTF_PGDSCTBL:
1738 if( !IsNewDoc() )
1739 SkipPageDescTbl();
1740 else
1741 ReadPageDescTbl();
1742 break;
1743 case RTF_LISTTABLE: ReadListTable(); break;
1744 case RTF_LISTOVERRIDETABLE: ReadListOverrideTable(); break;
1746 case RTF_LISTTEXT:
1747 GetAttrSet().Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 ));
1748 SkipGroup();
1749 break;
1751 case RTF_PN:
1752 if( bNewNumList )
1753 SkipGroup();
1754 else
1756 bStyleTabValid = TRUE;
1757 if (SwNumRule* pRule = ReadNumSecLevel( nToken ))
1759 GetAttrSet().Put( SwNumRuleItem( pRule->GetName() ));
1761 if( SFX_ITEM_SET != GetAttrSet().GetItemState( FN_PARAM_NUM_LEVEL, FALSE ))
1762 GetAttrSet().Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 ));
1765 break;
1768 case RTF_BKMKSTART:
1769 if(RTF_TEXTTOKEN == GetNextToken())
1770 mpBookmarkStart = new BookmarkPosition(*pPam);
1771 else
1772 SkipToken(-1);
1774 SkipGroup();
1775 break;
1777 case RTF_BKMKEND:
1778 if(RTF_TEXTTOKEN == GetNextToken())
1780 const String& sBookmark = aToken;
1781 KeyCode aEmptyKeyCode;
1782 if (mpBookmarkStart)
1784 BookmarkPosition aBookmarkEnd(*pPam);
1785 SwPaM aBookmarkRegion( mpBookmarkStart->maMkNode, mpBookmarkStart->mnMkCntnt,
1786 aBookmarkEnd.maMkNode, aBookmarkEnd.mnMkCntnt);
1787 if (*mpBookmarkStart == aBookmarkEnd)
1788 aBookmarkRegion.DeleteMark();
1789 pDoc->getIDocumentMarkAccess()->makeMark(aBookmarkRegion, sBookmark, IDocumentMarkAccess::BOOKMARK);
1791 delete mpBookmarkStart, mpBookmarkStart = 0;
1793 else
1794 SkipToken(-1);
1796 SkipGroup();
1797 break;
1800 case RTF_PNSECLVL:{
1801 if( bNewNumList)
1802 SkipGroup();
1803 else
1804 ReadNumSecLevel( nToken );
1805 break;
1808 case RTF_PNTEXT:
1809 case RTF_NONSHPPICT:
1810 SkipGroup();
1811 break;
1813 case RTF_DEFFORMAT:
1814 case RTF_DEFTAB:
1815 case RTF_DEFLANG:
1816 // sind zwar Dok-Controls, werden aber manchmal auch vor der
1817 // Font/Style/Color-Tabelle gesetzt!
1818 SvxRTFParser::NextToken( nToken );
1819 break;
1821 case RTF_PAGE:
1822 if (pTableNode==NULL) { //#117410#: A \page command within a table is ignored by Word.
1823 if (lcl_UsedPara(*pPam))
1824 InsertPara();
1825 CheckInsNewTblLine();
1826 pDoc->InsertPoolItem(*pPam,
1827 SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK), 0);
1829 break;
1831 case RTF_SECT:
1832 ReadSectControls( nToken );
1833 break;
1834 case RTF_CELL:
1835 // --> OD 2008-12-22 #i83368#
1836 mbReadCellWhileReadSwFly = bReadSwFly;
1837 // <--
1838 if (CantUseTables())
1839 InsertPara();
1840 else
1842 // Tabelle nicht mehr vorhanden ?
1843 if (USHRT_MAX != nInsTblRow && !pTableNode)
1844 NewTblLine(); // evt. Line copieren
1845 GotoNextBox();
1847 break;
1849 case RTF_ROW:
1850 bTrowdRead=false;
1851 if (!CantUseTables())
1853 // aus der Line raus
1854 nAktBox = 0;
1855 pTableNode = 0;
1856 // noch in der Tabelle drin?
1857 SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
1858 const SwTableNode* pTblNd = rIdx.GetNode().FindTableNode();
1859 if( pTblNd )
1861 // search the end of this row
1862 const SwStartNode* pBoxStt =
1863 rIdx.GetNode().FindTableBoxStartNode();
1864 const SwTableBox* pBox = pTblNd->GetTable().GetTblBox(
1865 pBoxStt->GetIndex() );
1866 const SwTableLine* pLn = pBox->GetUpper();
1867 pBox = pLn->GetTabBoxes()[ pLn->GetTabBoxes().Count() - 1 ];
1868 rIdx = *pBox->GetSttNd()->EndOfSectionNode();
1869 pPam->Move( fnMoveForward, fnGoNode );
1871 nInsTblRow = static_cast< USHORT >(GetOpenBrakets());
1872 SetPardTokenRead( FALSE );
1873 SwPaM aTmp(*pPam);
1874 aTmp.Move( fnMoveBackward, fnGoNode );
1876 ::SetProgressState( rInput.Tell(), pDoc->GetDocShell() );
1877 break;
1879 case RTF_INTBL:
1880 if (!CantUseTables())
1882 if( !pTableNode ) // Tabelle nicht mehr vorhanden ?
1884 if (RTF_TROWD != GetNextToken())
1885 NewTblLine(); // evt. Line copieren
1886 SkipToken(-1);
1888 else
1890 // Crsr nicht mehr in der Tabelle ?
1891 if( !pPam->GetNode()->FindTableNode() )
1893 // dann wieder in die letzte Box setzen
1894 // (kann durch einlesen von Flys geschehen!)
1895 pPam->GetPoint()->nNode = *pTableNode->EndOfSectionNode();
1896 pPam->Move( fnMoveBackward );
1900 break;
1902 case RTF_REVTBL:
1903 ReadRevTbl();
1904 break;
1906 case RTF_REVISED:
1907 pRedlineInsert = new SwFltRedline(nsRedlineType_t::REDLINE_INSERT, 0, DateTime(Date( 0 ), Time( 0 )));
1908 break;
1910 case RTF_DELETED:
1911 pRedlineDelete = new SwFltRedline(nsRedlineType_t::REDLINE_DELETE, 0, DateTime(Date( 0 ), Time( 0 )));
1912 break;
1914 case RTF_REVAUTH:
1916 sw::util::AuthorInfo aEntry( static_cast< USHORT >(nTokenValue) );
1917 USHORT nPos;
1919 if(pRedlineInsert)
1921 if (pAuthorInfos && pAuthorInfos->Seek_Entry(&aEntry, &nPos))
1923 if (const sw::util::AuthorInfo* pAuthor = pAuthorInfos->GetObject(nPos))
1925 pRedlineInsert->nAutorNo = pAuthor->nOurId;
1930 break;
1932 case RTF_REVAUTHDEL:
1934 sw::util::AuthorInfo aEntry( static_cast< short >(nTokenValue) );
1935 USHORT nPos;
1937 if(pRedlineDelete)
1939 if (pAuthorInfos && pAuthorInfos->Seek_Entry(&aEntry, &nPos))
1941 if (const sw::util::AuthorInfo* pAuthor = pAuthorInfos->GetObject(nPos))
1943 pRedlineDelete->nAutorNo = pAuthor->nOurId;
1948 break;
1950 case RTF_REVDTTM:
1951 if (pRedlineInsert != NULL)
1952 pRedlineInsert->aStamp = sw::ms::DTTM2DateTime(nTokenValue);
1954 break;
1956 case RTF_REVDTTMDEL:
1957 pRedlineDelete->aStamp = sw::ms::DTTM2DateTime(nTokenValue);
1958 break;
1961 case RTF_FLY_INPARA:
1962 // \pard und plain ueberlesen !
1963 if( '}' != GetNextToken() && '}' != GetNextToken() )
1965 // Zeichengebundener Fly in Fly
1966 ReadHeaderFooter( nToken );
1967 SetPardTokenRead( FALSE );
1969 break;
1971 case RTF_PGDSCNO:
1972 if( IsNewDoc() && bSwPageDesc &&
1973 USHORT(nTokenValue) < pDoc->GetPageDescCnt() )
1975 const SwPageDesc* pPgDsc =
1976 &const_cast<const SwDoc *>(pDoc)
1977 ->GetPageDesc( USHORT(nTokenValue) );
1978 CheckInsNewTblLine();
1979 pDoc->InsertPoolItem(*pPam, SwFmtPageDesc( pPgDsc ), 0);
1981 break;
1983 case RTF_COLUM:
1984 pDoc->InsertPoolItem(*pPam,
1985 SvxFmtBreakItem( SVX_BREAK_COLUMN_BEFORE, RES_BREAK ), 0);
1986 break;
1988 case RTF_DXFRTEXT: // werden nur im Zusammenhang mit Flys ausgewertet
1989 case RTF_DFRMTXTX:
1990 case RTF_DFRMTXTY:
1991 break;
1993 case RTF_CHDATE: eDateFmt = DF_SHORT; goto SETCHDATEFIELD;
1994 case RTF_CHDATEA: eDateFmt = DF_SSYS; goto SETCHDATEFIELD;
1995 case RTF_CHDATEL: eDateFmt = DF_LSYS; goto SETCHDATEFIELD;
1996 SETCHDATEFIELD:
1998 USHORT nSubType = DATEFLD, nWhich = RES_DATEFLD;
1999 ULONG nFormat = eDateFmt;
2000 sw3io_ConvertFromOldField( *pDoc, nWhich, nSubType, nFormat, 0x0110 );
2002 SwDateTimeField aDateFld( (SwDateTimeFieldType*)
2003 pDoc->GetSysFldType( RES_DATETIMEFLD ), DATEFLD, nFormat);
2004 CheckInsNewTblLine();
2005 pDoc->InsertPoolItem(*pPam, SwFmtFld( aDateFld ), 0);
2007 break;
2009 case RTF_CHTIME:
2011 USHORT nSubType = TIMEFLD, nWhich = RES_TIMEFLD;
2012 ULONG nFormat = TF_SSMM_24;
2013 sw3io_ConvertFromOldField( *pDoc, nWhich, nSubType, nFormat, 0x0110 );
2014 SwDateTimeField aTimeFld( (SwDateTimeFieldType*)
2015 pDoc->GetSysFldType( RES_DATETIMEFLD ), TIMEFLD, nFormat);
2016 CheckInsNewTblLine();
2017 pDoc->InsertPoolItem(*pPam, SwFmtFld( aTimeFld ), 0);
2019 break;
2021 case RTF_CHPGN:
2023 SwPageNumberField aPageFld( (SwPageNumberFieldType*)
2024 pDoc->GetSysFldType( RES_PAGENUMBERFLD ),
2025 PG_RANDOM, SVX_NUM_ARABIC );
2026 CheckInsNewTblLine();
2027 pDoc->InsertPoolItem(*pPam, SwFmtFld(aPageFld), 0);
2029 break;
2031 case RTF_CHFTN:
2032 bFootnoteAutoNum = TRUE;
2033 break;
2035 case RTF_NOFPAGES:
2036 if( IsNewDoc() && nTokenValue && -1 != nTokenValue )
2037 ((SwDocStat&)pDoc->GetDocStat()).nPage = (USHORT)nTokenValue;
2038 break;
2040 case RTF_NOFWORDS:
2041 if( IsNewDoc() && nTokenValue && -1 != nTokenValue )
2042 ((SwDocStat&)pDoc->GetDocStat()).nWord = (USHORT)nTokenValue;
2043 break;
2044 case RTF_NOFCHARS:
2045 if( IsNewDoc() && nTokenValue && -1 != nTokenValue )
2046 ((SwDocStat&)pDoc->GetDocStat()).nChar = (USHORT)nTokenValue;
2047 break;
2048 case RTF_LYTPRTMET:
2049 if (IsNewDoc())
2050 pDoc->set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, false);
2051 break;
2052 case RTF_U:
2054 CheckInsNewTblLine();
2055 if( nTokenValue )
2056 aToken = (sal_Unicode )nTokenValue;
2057 pDoc->InsertString( *pPam, aToken );
2059 break;
2061 case RTF_USERPROPS:
2062 ReadUserProperties(); // #i28758 For now we don't support user properties
2063 break;
2065 // RTF_SUBENTRYINDEX
2067 default:
2068 switch( nToken & ~(0xff | RTF_SWGDEFS) )
2070 case RTF_DOCFMT:
2071 ReadDocControls( nToken );
2072 break;
2073 case RTF_SECTFMT:
2074 ReadSectControls( nToken );
2075 break;
2076 case RTF_APOCTL:
2077 if (nReadFlyDepth < 10)
2079 nReadFlyDepth++;
2080 ReadFly( nToken );
2081 nReadFlyDepth--;
2083 break;
2085 case RTF_BRDRDEF | RTF_TABLEDEF:
2086 case RTF_SHADINGDEF | RTF_TABLEDEF:
2087 case RTF_TABLEDEF:
2088 ReadTable( nToken );
2089 break;
2091 case RTF_INFO:
2092 ReadInfo();
2093 break;
2095 default:
2096 if( USHRT_MAX != nInsTblRow &&
2097 (nInsTblRow > GetOpenBrakets() || IsPardTokenRead() ))
2098 nInsTblRow = USHRT_MAX;
2100 SvxRTFParser::NextToken( nToken );
2101 break;
2104 if( USHRT_MAX != nInsTblRow &&
2105 (nInsTblRow > GetOpenBrakets() || IsPardTokenRead() ))
2106 nInsTblRow = USHRT_MAX;
2111 void SwRTFParser::InsertText()
2113 bContainsPara = false;
2114 // dann fuege den String ein, ohne das Attribute am Ende
2115 // aufgespannt werden.
2116 CheckInsNewTblLine();
2118 if(pRedlineInsert)
2119 mpRedlineStack->open(*pPam->GetPoint(), *pRedlineInsert);
2120 if(pRedlineDelete)
2121 mpRedlineStack->open(*pPam->GetPoint(), *pRedlineDelete);
2123 pDoc->InsertString( *pPam, aToken );
2125 if(pRedlineDelete)
2127 mpRedlineStack->close(*pPam->GetPoint(), pRedlineDelete->eType);
2130 if(pRedlineInsert)
2132 mpRedlineStack->close(*pPam->GetPoint(), pRedlineInsert->eType);
2139 void SwRTFParser::InsertPara()
2141 bContainsPara = true;
2142 CheckInsNewTblLine();
2143 pDoc->AppendTxtNode(*pPam->GetPoint());
2145 // setze das default Style
2146 if( !bStyleTabValid )
2147 MakeStyleTab();
2149 SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 );
2150 if( !pColl )
2151 pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
2152 pDoc->SetTxtFmtColl( *pPam, pColl );
2154 ::SetProgressState( rInput.Tell(), pDoc->GetDocShell() );
2159 void SwRTFParser::MovePos( int bForward )
2161 if( bForward )
2162 pPam->Move( fnMoveForward );
2163 else
2164 pPam->Move( fnMoveBackward );
2167 int SwRTFParser::IsEndPara( SvxNodeIdx* pNd, xub_StrLen nCnt ) const
2169 SwCntntNode *pNode = pDoc->GetNodes()[pNd->GetIdx()]->GetCntntNode();
2170 return pNode && pNode->Len() == nCnt;
2173 bool SwRTFParser::UncompressableStackEntry(const SvxRTFItemStackType &rSet)
2174 const
2177 #i21961#
2178 Seeing as CHARFMT sets all the properties of the charfmt itself, its not
2179 good enough to just see it as a single property from the point of
2180 compressing property sets. If bold and charfmt are in a child, and bold is
2181 in the parent, removing bold from the child will not result in the same
2182 thing, if the charfmt removes bold itself for example
2184 bool bRet = false;
2185 if (rSet.GetAttrSet().Count())
2188 if (SFX_ITEM_SET ==
2189 rSet.GetAttrSet().GetItemState(RES_TXTATR_CHARFMT, FALSE))
2191 bRet = true;
2194 return bRet;
2197 void SwRTFParser::SetEndPrevPara( SvxNodeIdx*& rpNodePos, xub_StrLen& rCntPos )
2199 SwNodeIndex aIdx( pPam->GetPoint()->nNode );
2200 SwCntntNode* pNode = pDoc->GetNodes().GoPrevious( &aIdx );
2201 if( !pNode )
2203 ASSERT( FALSE, "keinen vorherigen ContentNode gefunden" );
2206 rpNodePos = new SwNodeIdx( aIdx );
2207 rCntPos = pNode->Len();
2210 void SwRTFParser::SetAttrInDoc( SvxRTFItemStackType &rSet )
2212 ULONG nSNd = rSet.GetSttNodeIdx(), nENd = rSet.GetEndNodeIdx();
2213 xub_StrLen nSCnt = rSet.GetSttCnt(), nECnt = rSet.GetEndCnt();
2215 SwPaM aPam( *pPam->GetPoint() );
2217 #ifndef PRODUCT
2218 ASSERT( nSNd <= nENd, "Start groesser als Ende" );
2219 SwNode* pDebugNd = pDoc->GetNodes()[ nSNd ];
2220 ASSERT( pDebugNd->IsCntntNode(), "Start kein ContentNode" );
2221 pDebugNd = pDoc->GetNodes()[ nENd ];
2222 ASSERT( pDebugNd->IsCntntNode(), "Ende kein ContentNode" );
2223 #endif
2225 SwCntntNode* pCNd = pDoc->GetNodes()[ nSNd ]->GetCntntNode();
2226 aPam.GetPoint()->nNode = nSNd;
2227 aPam.GetPoint()->nContent.Assign( pCNd, nSCnt );
2228 aPam.SetMark();
2229 if( nENd == nSNd )
2230 aPam.GetPoint()->nContent = nECnt;
2231 else
2233 aPam.GetPoint()->nNode = nENd;
2234 pCNd = aPam.GetCntntNode();
2235 aPam.GetPoint()->nContent.Assign( pCNd, nECnt );
2238 // setze ueber den Bereich das entsprechende Style
2239 if( rSet.StyleNo() )
2241 // setze jetzt das Style
2242 if( !bStyleTabValid )
2243 MakeStyleTab();
2244 SwTxtFmtColl* pColl = aTxtCollTbl.Get( rSet.StyleNo() );
2245 if( pColl )
2246 pDoc->SetTxtFmtColl( aPam, pColl, false );
2249 const SfxPoolItem* pItem;
2250 const SfxPoolItem* pCharFmt;
2251 if (rSet.GetAttrSet().Count() )
2254 // falls eine Zeichenvorlage im Set steht, deren Attribute
2255 // aus dem Set loeschen. Sonst sind diese doppelt, was man ja
2256 // nicht will.
2257 if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(
2258 RES_TXTATR_CHARFMT, FALSE, &pCharFmt ) &&
2259 ((SwFmtCharFmt*)pCharFmt)->GetCharFmt() )
2261 const String& rName = ((SwFmtCharFmt*)pCharFmt)->GetCharFmt()->GetName();
2262 SvxRTFStyleType* pStyle = GetStyleTbl().First();
2263 do {
2264 if( pStyle->bIsCharFmt && pStyle->sName == rName )
2266 // alle Attribute, die schon vom Style definiert sind, aus dem
2267 // akt. AttrSet entfernen
2268 SfxItemSet &rAttrSet = rSet.GetAttrSet(),
2269 &rStyleSet = pStyle->aAttrSet;
2270 SfxItemIter aIter( rAttrSet );
2271 USHORT nWhich = aIter.GetCurItem()->Which();
2272 while( TRUE )
2274 const SfxPoolItem* pI;
2275 if( SFX_ITEM_SET == rStyleSet.GetItemState(
2276 nWhich, FALSE, &pI ) && *pI == *aIter.GetCurItem())
2277 rAttrSet.ClearItem( nWhich ); // loeschen
2279 if( aIter.IsAtEnd() )
2280 break;
2281 nWhich = aIter.NextItem()->Which();
2283 break;
2285 } while( 0 != (pStyle = GetStyleTbl().Next()) );
2287 pDoc->InsertPoolItem(aPam, *pCharFmt, 0);
2288 rSet.GetAttrSet().ClearItem(RES_TXTATR_CHARFMT); //test hack
2290 if (rSet.GetAttrSet().Count())
2292 // dann setze ueber diesen Bereich die Attrbiute
2293 SetSwgValues(rSet.GetAttrSet());
2294 pDoc->InsertItemSet(aPam, rSet.GetAttrSet(),
2295 nsSetAttrMode::SETATTR_DONTCHGNUMRULE);
2299 if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(
2300 FN_PARAM_NUM_LEVEL, FALSE, &pItem ))
2302 // dann ueber den Bereich an den Nodes das NodeNum setzen
2303 for( ULONG n = nSNd; n <= nENd; ++n )
2305 SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode();
2306 if( pTxtNd )
2308 pTxtNd->SetAttrListLevel((BYTE) ((SfxUInt16Item*)pItem)->GetValue());
2309 // Update vom LR-Space abschalten?
2314 if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(
2315 RES_PARATR_NUMRULE, FALSE, &pItem ))
2317 const SwNumRule* pRule = pDoc->FindNumRulePtr(
2318 ((SwNumRuleItem*)pItem)->GetValue() );
2319 if( pRule && ( pRule->IsContinusNum() || !bNewNumList ))
2321 // diese Rule hat keinen Level, also muss die Einrueckung
2322 // erhalten bleiben!
2323 // dann ueber den Bereich an den Nodes das Flag zuruecksetzen
2324 for( ULONG n = nSNd; n <= nENd; ++n )
2326 SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode();
2327 if( pTxtNd )
2329 // Update vom LR-Space abschalten
2330 pTxtNd->SetNumLSpace( FALSE );
2336 bool bNoNum = true;
2337 if (
2338 (SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(RES_PARATR_NUMRULE))
2339 || (SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(FN_PARAM_NUM_LEVEL))
2342 bNoNum = false;
2345 if (bNoNum)
2347 for( ULONG n = nSNd; n <= nENd; ++n )
2349 SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode();
2350 if( pTxtNd )
2352 pTxtNd->SetAttr(
2353 *GetDfltAttr(RES_PARATR_NUMRULE));
2359 DocPageInformation::DocPageInformation()
2360 : maBox( RES_BOX ),
2361 mnPaperw(12240), mnPaperh(15840), mnMargl(1800), mnMargr(1800),
2362 mnMargt(1440), mnMargb(1440), mnGutter(0), mnPgnStart(1), mbFacingp(false),
2363 mbLandscape(false), mbRTLdoc(false)
2367 SectPageInformation::SectPageInformation(const DocPageInformation &rDoc)
2368 : maBox(rDoc.maBox), mpTitlePageHdFt(0), mpPageHdFt(0),
2369 mnPgwsxn(rDoc.mnPaperw), mnPghsxn(rDoc.mnPaperh), mnMarglsxn(rDoc.mnMargl),
2370 mnMargrsxn(rDoc.mnMargr), mnMargtsxn(rDoc.mnMargt),
2371 mnMargbsxn(rDoc.mnMargb), mnGutterxsn(rDoc.mnGutter), mnHeadery(720),
2372 mnFootery(720), mnPgnStarts(rDoc.mnPgnStart), mnCols(1), mnColsx(720),
2373 mnStextflow(rDoc.mbRTLdoc ? 3 : 0), mnBkc(2), mbLndscpsxn(rDoc.mbLandscape),
2374 mbTitlepg(false), mbFacpgsxn(rDoc.mbFacingp), mbRTLsection(rDoc.mbRTLdoc),
2375 mbPgnrestart(false), mbTitlePageHdFtUsed(false), mbPageHdFtUsed(false)
2379 SectPageInformation::SectPageInformation(const SectPageInformation &rSect)
2380 : maColumns(rSect.maColumns), maBox(rSect.maBox),
2381 maNumType(rSect.maNumType), mpTitlePageHdFt(rSect.mpTitlePageHdFt),
2382 mpPageHdFt(rSect.mpPageHdFt), mnPgwsxn(rSect.mnPgwsxn),
2383 mnPghsxn(rSect.mnPghsxn), mnMarglsxn(rSect.mnMarglsxn),
2384 mnMargrsxn(rSect.mnMargrsxn), mnMargtsxn(rSect.mnMargtsxn),
2385 mnMargbsxn(rSect.mnMargbsxn), mnGutterxsn(rSect.mnGutterxsn),
2386 mnHeadery(rSect.mnHeadery), mnFootery(rSect.mnFootery),
2387 mnPgnStarts(rSect.mnPgnStarts), mnCols(rSect.mnCols),
2388 mnColsx(rSect.mnColsx), mnStextflow(rSect.mnStextflow), mnBkc(rSect.mnBkc),
2389 mbLndscpsxn(rSect.mbLndscpsxn), mbTitlepg(rSect.mbTitlepg),
2390 mbFacpgsxn(rSect.mbFacpgsxn), mbRTLsection(rSect.mbRTLsection),
2391 mbPgnrestart(rSect.mbPgnrestart),
2392 mbTitlePageHdFtUsed(rSect.mbTitlePageHdFtUsed),
2393 mbPageHdFtUsed(rSect.mbPageHdFtUsed)
2397 rtfSection::rtfSection(const SwPosition &rPos,
2398 const SectPageInformation &rPageInfo)
2399 : maStart(rPos.nNode), maPageInfo(rPageInfo), mpSection(0), mpTitlePage(0),
2400 mpPage(0)
2404 void rtfSections::push_back(const rtfSection &rSect)
2406 if (!maSegments.empty() && (maSegments.back().maStart == rSect.maStart))
2407 maSegments.pop_back();
2408 maSegments.push_back(rSect);
2411 // lese alle Dokument-Controls ein
2412 void SwRTFParser::SetPageInformationAsDefault(const DocPageInformation &rInfo)
2414 //If we are at the beginning of the document then start the document with
2415 //a segment with these properties. See #i14982# for this requirement
2416 rtfSection aSect(*pPam->GetPoint(), SectPageInformation(rInfo));
2417 if (maSegments.empty() || (maSegments.back().maStart == aSect.maStart))
2418 maSegments.push_back(aSect);
2420 if (!bSwPageDesc && IsNewDoc())
2422 SwFmtFrmSize aFrmSize(ATT_FIX_SIZE, rInfo.mnPaperw, rInfo.mnPaperh);
2424 SvxLRSpaceItem aLR( static_cast< USHORT >(rInfo.mnMargl), static_cast< USHORT >(rInfo.mnMargr), 0, 0, RES_LR_SPACE );
2425 SvxULSpaceItem aUL( static_cast< USHORT >(rInfo.mnMargt), static_cast< USHORT >(rInfo.mnMargb), RES_UL_SPACE );
2427 UseOnPage eUseOn;
2428 if (rInfo.mbFacingp)
2429 eUseOn = UseOnPage(nsUseOnPage::PD_MIRROR | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE);
2430 else
2431 eUseOn = UseOnPage(nsUseOnPage::PD_ALL | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE);
2433 USHORT nPgStart = static_cast< USHORT >(rInfo.mnPgnStart);
2435 SvxFrameDirectionItem aFrmDir(rInfo.mbRTLdoc ?
2436 FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR);
2438 // direkt an der Standartseite drehen
2439 SwPageDesc& rPg = pDoc->_GetPageDesc( 0 );
2440 rPg.WriteUseOn( eUseOn );
2442 if (rInfo.mbLandscape)
2443 rPg.SetLandscape(true);
2445 SwFrmFmt &rFmt1 = rPg.GetMaster(), &rFmt2 = rPg.GetLeft();
2447 rFmt1.SetFmtAttr( aFrmSize ); rFmt2.SetFmtAttr( aFrmSize );
2448 rFmt1.SetFmtAttr( aLR ); rFmt2.SetFmtAttr( aLR );
2449 rFmt1.SetFmtAttr( aUL ); rFmt2.SetFmtAttr( aUL );
2450 rFmt1.SetFmtAttr( aFrmDir ); rFmt2.SetFmtAttr( aFrmDir );
2452 // StartNummer der Seiten setzen
2453 if (nPgStart != 1)
2455 SwFmtPageDesc aPgDsc( &rPg );
2456 aPgDsc.SetNumOffset( nPgStart );
2457 pDoc->InsertPoolItem( *pPam, aPgDsc, 0 );
2462 void SwRTFParser::SetBorderLine(SvxBoxItem& rBox, sal_uInt16 nLine)
2464 int bWeiter = true;
2465 short nLineThickness = 1;
2466 short nPageDistance = 0;
2467 BYTE nCol = 0;
2468 short nIdx = 0;
2470 int nToken = GetNextToken();
2471 do {
2472 switch( nToken )
2474 case RTF_BRDRS:
2475 nIdx = 1;
2476 break;
2478 case RTF_BRDRDB:
2479 nIdx = 3;
2480 break;
2482 case RTF_BRDRTRIPLE:
2483 nIdx = 10;
2484 break;
2486 case RTF_BRDRTNTHSG:
2487 nIdx = 11;
2488 break;
2490 case RTF_BRDRTHTNSG:
2491 nIdx = 12;
2492 break;
2494 case RTF_BRDRTNTHTNSG:
2495 nIdx = 13;
2496 break;
2498 case RTF_BRDRTNTHMG:
2499 nIdx = 14;
2500 break;
2502 case RTF_BRDRTHTNMG:
2503 nIdx = 15;
2504 break;
2506 case RTF_BRDRTNTHTNMG:
2507 nIdx = 16;
2508 break;
2510 case RTF_BRDRTNTHLG:
2511 nIdx = 17;
2512 break;
2514 case RTF_BRDRTHTNLG:
2515 nIdx = 18;
2516 break;
2518 case RTF_BRDRTNTHTNLG:
2519 nIdx = 19;
2520 break;
2522 case RTF_BRDRWAVY:
2523 nIdx = 20;
2524 break;
2526 case RTF_BRDRWAVYDB:
2527 nIdx = 21;
2528 break;
2530 case RTF_BRDREMBOSS:
2531 nIdx = 24;
2532 break;
2534 case RTF_BRDRENGRAVE:
2535 nIdx = 25;
2536 break;
2538 case RTF_BRSP:
2539 nPageDistance = static_cast< short >(nTokenValue);
2540 break;
2542 case RTF_BRDRDOT: // SO does not have dashed or dotted lines
2543 case RTF_BRDRDASH:
2544 case RTF_BRDRDASHSM:
2545 case RTF_BRDRDASHD:
2546 case RTF_BRDRDASHDD:
2547 case RTF_BRDRDASHDOTSTR:
2548 case RTF_BRDRSH: // shading not supported
2549 case RTF_BRDRCF: // colors not supported
2550 break;
2552 case RTF_BRDRW:
2553 nLineThickness = static_cast< short >(nTokenValue);
2554 break;
2555 default:
2556 bWeiter = false;
2557 SkipToken(-1);
2558 break;
2560 if (bWeiter)
2561 nToken = GetNextToken();
2562 } while (bWeiter && IsParserWorking());
2564 GetLineIndex(rBox, nLineThickness, nPageDistance, nCol, nIdx, nLine, nLine, 0);
2567 // lese alle Dokument-Controls ein
2568 void SwRTFParser::ReadDocControls( int nToken )
2570 int bWeiter = true;
2572 SwFtnInfo aFtnInfo;
2573 SwEndNoteInfo aEndInfo;
2574 bool bSetHyph = false;
2576 BOOL bEndInfoChgd = FALSE, bFtnInfoChgd = FALSE;
2578 do {
2579 USHORT nValue = USHORT( nTokenValue );
2580 switch( nToken )
2582 case RTF_RTLDOC:
2583 maPageDefaults.mbRTLdoc = true;
2584 break;
2585 case RTF_LTRDOC:
2586 maPageDefaults.mbRTLdoc = false;
2587 break;
2588 case RTF_LANDSCAPE:
2589 maPageDefaults.mbLandscape = true;
2590 break;
2591 case RTF_PAPERW:
2592 if( 0 < nTokenValue )
2593 maPageDefaults.mnPaperw = nTokenValue;
2594 break;
2595 case RTF_PAPERH:
2596 if( 0 < nTokenValue )
2597 maPageDefaults.mnPaperh = nTokenValue;
2598 break;
2599 case RTF_MARGL:
2600 if( 0 <= nTokenValue )
2601 maPageDefaults.mnMargl = nTokenValue;
2602 break;
2603 case RTF_MARGR:
2604 if( 0 <= nTokenValue )
2605 maPageDefaults.mnMargr = nTokenValue;
2606 break;
2607 case RTF_MARGT:
2608 if( 0 <= nTokenValue )
2609 maPageDefaults.mnMargt = nTokenValue;
2610 break;
2611 case RTF_MARGB:
2612 if( 0 <= nTokenValue )
2613 maPageDefaults.mnMargb = nTokenValue;
2614 break;
2615 case RTF_FACINGP:
2616 maPageDefaults.mbFacingp = true;
2617 break;
2618 case RTF_PGNSTART:
2619 maPageDefaults.mnPgnStart = nTokenValue;
2620 break;
2621 case RTF_ENDDOC:
2622 case RTF_ENDNOTES:
2623 aFtnInfo.ePos = FTNPOS_CHAPTER; bFtnInfoChgd = TRUE;
2624 break;
2625 case RTF_FTNTJ:
2626 case RTF_FTNBJ:
2627 aFtnInfo.ePos = FTNPOS_PAGE; bFtnInfoChgd = TRUE;
2628 break;
2630 case RTF_AENDDOC:
2631 case RTF_AENDNOTES:
2632 case RTF_AFTNTJ:
2633 case RTF_AFTNBJ:
2634 case RTF_AFTNRESTART:
2635 case RTF_AFTNRSTCONT:
2636 break; // wir kenn nur am Doc Ende und Doc weite Num.!
2638 case RTF_FTNSTART:
2639 if( nValue )
2641 aFtnInfo.nFtnOffset = nValue-1;
2642 bFtnInfoChgd = TRUE;
2644 break;
2645 case RTF_AFTNSTART:
2646 if( nValue )
2648 aEndInfo.nFtnOffset = nValue-1;
2649 bEndInfoChgd = TRUE;
2651 break;
2652 case RTF_FTNRSTPG:
2653 aFtnInfo.eNum = FTNNUM_PAGE; bFtnInfoChgd = TRUE;
2654 break;
2655 case RTF_FTNRESTART:
2656 aFtnInfo.eNum = FTNNUM_CHAPTER; bFtnInfoChgd = TRUE;
2657 break;
2658 case RTF_FTNRSTCONT:
2659 aFtnInfo.eNum = FTNNUM_DOC; bFtnInfoChgd = TRUE;
2660 break;
2662 case RTF_FTNNAR:
2663 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ARABIC); bFtnInfoChgd = TRUE; break;
2664 case RTF_FTNNALC:
2665 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER_N); bFtnInfoChgd = TRUE; break;
2666 case RTF_FTNNAUC:
2667 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_UPPER_LETTER_N); bFtnInfoChgd = TRUE; break;
2668 case RTF_FTNNRLC:
2669 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER); bFtnInfoChgd = TRUE; break;
2670 case RTF_FTNNRUC:
2671 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_UPPER); bFtnInfoChgd = TRUE; break;
2672 case RTF_FTNNCHI:
2673 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL); bFtnInfoChgd = TRUE; break;
2675 case RTF_AFTNNAR:
2676 aEndInfo.aFmt.SetNumberingType(SVX_NUM_ARABIC); bEndInfoChgd = TRUE; break;
2677 case RTF_AFTNNALC:
2678 aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER_N);
2679 bEndInfoChgd = TRUE;
2680 break;
2681 case RTF_AFTNNAUC:
2682 aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_UPPER_LETTER_N);
2683 bEndInfoChgd = TRUE;
2684 break;
2685 case RTF_AFTNNRLC:
2686 aEndInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER);
2687 bEndInfoChgd = TRUE;
2688 break;
2689 case RTF_AFTNNRUC:
2690 aEndInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_UPPER);
2691 bEndInfoChgd = TRUE;
2692 break;
2693 case RTF_AFTNNCHI:
2694 aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
2695 bEndInfoChgd = TRUE;
2696 break;
2697 case RTF_HYPHAUTO:
2698 if (nTokenValue)
2699 bSetHyph = true;
2700 //FOO//
2701 break;
2702 case RTF_PGBRDRT:
2703 SetBorderLine(maPageDefaults.maBox, BOX_LINE_TOP);
2704 break;
2706 case RTF_PGBRDRB:
2707 SetBorderLine(maPageDefaults.maBox, BOX_LINE_BOTTOM);
2708 break;
2710 case RTF_PGBRDRL:
2711 SetBorderLine(maPageDefaults.maBox, BOX_LINE_LEFT);
2712 break;
2714 case RTF_PGBRDRR:
2715 SetBorderLine(maPageDefaults.maBox, BOX_LINE_RIGHT);
2716 break;
2718 case '{':
2720 short nSkip = 0;
2721 if( RTF_IGNOREFLAG != GetNextToken() )
2722 nSkip = -1;
2723 else if( RTF_DOCFMT != (( nToken = GetNextToken() )
2724 & ~(0xff | RTF_SWGDEFS)) )
2725 nSkip = -2;
2726 else
2728 SkipGroup(); // erstmal komplett ueberlesen
2729 // ueberlese noch die schliessende Klammer
2730 GetNextToken();
2732 if( nSkip )
2734 SkipToken( nSkip ); // Ignore wieder zurueck
2735 bWeiter = FALSE;
2738 break;
2740 default:
2741 if( RTF_DOCFMT == (nToken & ~(0xff | RTF_SWGDEFS)) ||
2742 RTF_UNKNOWNCONTROL == nToken )
2743 SvxRTFParser::NextToken( nToken );
2744 else
2745 bWeiter = FALSE;
2746 break;
2748 if( bWeiter )
2749 nToken = GetNextToken();
2750 } while( bWeiter && IsParserWorking() );
2752 if (IsNewDoc())
2754 if( bEndInfoChgd )
2755 pDoc->SetEndNoteInfo( aEndInfo );
2756 if( bFtnInfoChgd )
2757 pDoc->SetFtnInfo( aFtnInfo );
2760 if (!bSwPageDesc)
2762 SetPageInformationAsDefault(maPageDefaults);
2764 MakeStyleTab();
2766 SwTxtFmtColl* pColl = aTxtCollTbl.Get(0);
2767 if (!pColl)
2769 pColl = pDoc->GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false );
2772 ASSERT(pColl, "impossible to have no standard style");
2774 if (pColl)
2776 if (
2777 IsNewDoc() && bSetHyph &&
2778 SFX_ITEM_SET != pColl->GetItemState(RES_PARATR_HYPHENZONE,
2779 false)
2782 pColl->SetFmtAttr(SvxHyphenZoneItem(true, RES_PARATR_HYPHENZONE));
2785 pDoc->SetTxtFmtColl( *pPam, pColl );
2789 SkipToken( -1 );
2792 void SwRTFParser::MakeStyleTab()
2794 // dann erzeuge aus der SvxStyle-Tabelle die Swg-Collections
2795 if( GetStyleTbl().Count() )
2797 USHORT nValidOutlineLevels = 0;
2798 if( !IsNewDoc() )
2800 // search all outlined collections
2801 //BYTE nLvl;
2802 const SwTxtFmtColls& rColls = *pDoc->GetTxtFmtColls();
2803 for( USHORT n = rColls.Count(); n; )
2804 //if( MAXLEVEL > (nLvl = rColls[ --n ]->GetOutlineLevel() ))//#outline level,zhaojianwei
2805 // nValidOutlineLevels |= 1 << nLvl;
2806 if( rColls[ --n ]->IsAssignedToListLevelOfOutlineStyle())
2807 nValidOutlineLevels |= 1 << rColls[ n ]->GetAssignedOutlineStyleLevel();//<-end,zhaojianwei
2810 SvxRTFStyleType* pStyle = GetStyleTbl().First();
2811 do {
2812 USHORT nNo = USHORT( GetStyleTbl().GetCurKey() );
2813 if( pStyle->bIsCharFmt )
2815 if( !aCharFmtTbl.Get( nNo ) )
2816 // existiert noch nicht, also anlegen
2817 MakeCharStyle( nNo, *pStyle );
2819 else if( !aTxtCollTbl.Get( nNo ) )
2821 // existiert noch nicht, also anlegen
2822 MakeStyle( nNo, *pStyle );
2825 } while( 0 != (pStyle = GetStyleTbl().Next()) );
2826 bStyleTabValid = TRUE;
2830 BOOL lcl_SetFmtCol( SwFmt& rFmt, USHORT nCols, USHORT nColSpace,
2831 const SvUShorts& rColumns )
2833 BOOL bSet = FALSE;
2834 if( nCols && USHRT_MAX != nCols )
2836 SwFmtCol aCol;
2837 if( USHRT_MAX == nColSpace )
2838 nColSpace = 720;
2840 aCol.Init( nCols, nColSpace, USHRT_MAX );
2841 if( nCols == ( rColumns.Count() / 2 ) )
2843 aCol._SetOrtho( FALSE );
2844 USHORT nWishWidth = 0, nHalfPrev = 0;
2845 for( USHORT n = 0, i = 0; n < rColumns.Count(); n += 2, ++i )
2847 SwColumn* pCol = aCol.GetColumns()[ i ];
2848 pCol->SetLeft( nHalfPrev );
2849 USHORT nSp = rColumns[ n+1 ];
2850 nHalfPrev = nSp / 2;
2851 pCol->SetRight( nSp - nHalfPrev );
2852 pCol->SetWishWidth( rColumns[ n ] +
2853 pCol->GetLeft() + pCol->GetRight() );
2854 nWishWidth = nWishWidth + pCol->GetWishWidth();
2856 aCol.SetWishWidth( nWishWidth );
2858 rFmt.SetFmtAttr( aCol );
2859 bSet = TRUE;
2861 return bSet;
2864 void SwRTFParser::DoHairyWriterPageDesc(int nToken)
2866 int bWeiter = TRUE;
2867 do {
2868 if( '{' == nToken )
2870 switch( nToken = GetNextToken() )
2872 case RTF_IGNOREFLAG:
2873 if( RTF_SECTFMT != (( nToken = GetNextToken() )
2874 & ~(0xff | RTF_SWGDEFS)) )
2876 SkipToken( -2 ); // Ignore und Token wieder zurueck
2877 bWeiter = FALSE;
2878 break;
2880 // kein break, Gruppe ueberspringen
2882 case RTF_FOOTER:
2883 case RTF_HEADER:
2884 case RTF_FOOTERR:
2885 case RTF_HEADERR:
2886 case RTF_FOOTERL:
2887 case RTF_HEADERL:
2888 case RTF_FOOTERF:
2889 case RTF_HEADERF:
2890 SkipGroup(); // erstmal komplett ueberlesen
2891 // ueberlese noch die schliessende Klammer
2892 GetNextToken();
2893 break;
2895 default:
2896 SkipToken( -1 ); // Ignore wieder zurueck
2897 bWeiter = FALSE;
2898 break;
2901 else if( RTF_SECTFMT == (nToken & ~(0xff | RTF_SWGDEFS)) ||
2902 RTF_UNKNOWNCONTROL == nToken )
2903 SvxRTFParser::NextToken( nToken );
2904 else
2905 bWeiter = FALSE;
2906 if( bWeiter )
2907 nToken = GetNextToken();
2908 } while( bWeiter && IsParserWorking() );
2909 SkipToken( -1 ); // letztes Token wieder zurueck
2910 return;
2913 void SwRTFParser::ReadSectControls( int nToken )
2915 //this is some hairy stuff to try and retain writer style page descriptors
2916 //in rtf, almost certainy a bad idea, but we've inherited it, so here it
2917 //stays
2918 if (bInPgDscTbl)
2920 DoHairyWriterPageDesc(nToken);
2921 return;
2924 ASSERT(!maSegments.empty(), "suspicious to have a section with no "
2925 "page info, though probably legal");
2926 if (maSegments.empty())
2928 maSegments.push_back(rtfSection(*pPam->GetPoint(),
2929 SectPageInformation(maPageDefaults)));
2932 SectPageInformation aNewSection(maSegments.back().maPageInfo);
2934 bool bNewSection = false;
2935 bool bNewSectionHeader = false;
2936 const SwFmtHeader* _pKeepHeader = NULL;
2937 const SwFmtFooter* _pKeepFooter = NULL;
2938 int bWeiter = true;
2939 bool bKeepFooter = false;
2940 do {
2941 USHORT nValue = USHORT( nTokenValue );
2942 switch( nToken )
2944 case RTF_SECT:
2945 bNewSection = true;
2946 bForceNewTable = true; // #117882#
2947 break;
2948 case RTF_SECTD: {
2949 //Reset to page defaults
2950 SwPageDesc* oldPageDesc=aNewSection.mpPageHdFt;
2951 aNewSection = SectPageInformation(maPageDefaults);
2952 aNewSection.mpPageHdFt=oldPageDesc;
2953 _pKeepHeader = NULL;
2954 _pKeepFooter = NULL;
2955 } break;
2956 case RTF_PGWSXN:
2957 if (0 < nTokenValue)
2958 aNewSection.mnPgwsxn = nTokenValue;
2959 break;
2960 case RTF_PGHSXN:
2961 if (0 < nTokenValue)
2962 aNewSection.mnPghsxn = nTokenValue;
2963 break;
2964 case RTF_MARGLSXN:
2965 if (0 <= nTokenValue)
2966 aNewSection.mnMarglsxn = nTokenValue;
2967 break;
2968 case RTF_MARGRSXN:
2969 if (0 <= nTokenValue)
2970 aNewSection.mnMargrsxn = nTokenValue;
2971 break;
2972 case RTF_MARGTSXN:
2973 if (0 <= nTokenValue)
2974 aNewSection.mnMargtsxn = nTokenValue;
2975 break;
2976 case RTF_MARGBSXN:
2977 if (0 <= nTokenValue)
2978 aNewSection.mnMargbsxn = nTokenValue;
2979 break;
2980 case RTF_FACPGSXN:
2981 aNewSection.mbFacpgsxn = true;
2982 break;
2983 case RTF_HEADERY:
2984 aNewSection.mnHeadery = nTokenValue;
2985 break;
2986 case RTF_FOOTERY:
2987 aNewSection.mnFootery = nTokenValue;
2988 break;
2989 case RTF_LNDSCPSXN:
2990 aNewSection.mbLndscpsxn = true;
2991 break;
2992 case RTF_PGNSTARTS:
2993 aNewSection.mnPgnStarts = nTokenValue;
2994 break;
2995 case RTF_PGNDEC:
2996 aNewSection.maNumType.SetNumberingType(SVX_NUM_ARABIC);
2997 break;
2998 case RTF_PGNUCRM:
2999 aNewSection.maNumType.SetNumberingType(SVX_NUM_ROMAN_UPPER);
3000 break;
3001 case RTF_PGNLCRM:
3002 aNewSection.maNumType.SetNumberingType(SVX_NUM_ROMAN_LOWER);
3003 break;
3004 case RTF_PGNUCLTR:
3005 aNewSection.maNumType.SetNumberingType(
3006 SVX_NUM_CHARS_UPPER_LETTER_N);
3007 break;
3008 case RTF_PGNLCLTR:
3009 aNewSection.maNumType.SetNumberingType(
3010 SVX_NUM_CHARS_LOWER_LETTER_N);
3011 break;
3012 case RTF_SBKNONE:
3013 aNewSection.mnBkc = 0;
3014 break;
3015 case RTF_SBKCOL:
3016 aNewSection.mnBkc = 1;
3017 break;
3018 case RTF_PGBRDRT:
3019 SetBorderLine(aNewSection.maBox, BOX_LINE_TOP);
3020 break;
3022 case RTF_PGBRDRB:
3023 SetBorderLine(aNewSection.maBox, BOX_LINE_BOTTOM);
3024 break;
3026 case RTF_PGBRDRL:
3027 SetBorderLine(aNewSection.maBox, BOX_LINE_LEFT);
3028 break;
3030 case RTF_PGBRDRR:
3031 SetBorderLine(aNewSection.maBox, BOX_LINE_RIGHT);
3032 break;
3034 case RTF_PGBRDROPT:
3035 case RTF_ENDNHERE:
3036 case RTF_BINFSXN:
3037 case RTF_BINSXN:
3038 case RTF_SBKPAGE:
3039 case RTF_SBKEVEN:
3040 case RTF_SBKODD:
3041 case RTF_LINEBETCOL:
3042 case RTF_LINEMOD:
3043 case RTF_LINEX:
3044 case RTF_LINESTARTS:
3045 case RTF_LINERESTART:
3046 case RTF_LINEPAGE:
3047 case RTF_LINECONT:
3048 case RTF_GUTTERSXN:
3049 case RTF_PGNCONT:
3050 case RTF_PGNRESTART:
3051 case RTF_PGNX:
3052 case RTF_PGNY:
3053 case RTF_VERTALT:
3054 case RTF_VERTALB:
3055 case RTF_VERTALC:
3056 case RTF_VERTALJ:
3057 break;
3058 case RTF_TITLEPG:
3059 aNewSection.mbTitlepg = true;
3060 break;
3061 case RTF_HEADER:
3062 case RTF_HEADERL:
3063 case RTF_HEADERR:
3064 if (aNewSection.mpPageHdFt!=NULL)
3066 _pKeepHeader = NULL;
3067 bKeepFooter = true; // #i82008
3068 _pKeepFooter = &aNewSection.mpPageHdFt->GetMaster().GetFooter();
3070 case RTF_FOOTER:
3071 case RTF_FOOTERL:
3072 case RTF_FOOTERR:
3073 if (aNewSection.mpPageHdFt!=NULL && !bKeepFooter )
3075 _pKeepFooter = NULL;
3076 _pKeepHeader = &aNewSection.mpPageHdFt->GetMaster().GetHeader();
3078 bKeepFooter = false;
3079 if (!bNewSectionHeader) { //see #117914# topic 2). If a header is redefined in a section
3080 bNewSectionHeader=true; // a new header must be created.
3081 aNewSection.mpPageHdFt=NULL;
3083 if (!aNewSection.mpPageHdFt)
3085 String aName(RTL_CONSTASCII_STRINGPARAM("rtfHdFt"));
3086 aName += String::CreateFromInt32(maSegments.size());
3087 sal_uInt16 nPageNo = pDoc->MakePageDesc(aName);
3088 aNewSection.mpPageHdFt = &pDoc->_GetPageDesc(nPageNo);
3089 aNewSection.mbPageHdFtUsed = true;
3090 maSegments.maDummyPageNos.push_back(nPageNo);
3092 ReadHeaderFooter(nToken, aNewSection.mpPageHdFt);
3093 if (_pKeepHeader) aNewSection.mpPageHdFt->GetMaster().SetFmtAttr(*_pKeepHeader);
3094 if (_pKeepFooter) aNewSection.mpPageHdFt->GetMaster().SetFmtAttr(*_pKeepFooter);
3095 break;
3096 case RTF_FOOTERF:
3097 case RTF_HEADERF:
3098 if (!aNewSection.mpTitlePageHdFt)
3100 String aTitle(RTL_CONSTASCII_STRINGPARAM("rtfTitleHdFt"));
3101 aTitle += String::CreateFromInt32(maSegments.size());
3102 sal_uInt16 nPageNo = pDoc->MakePageDesc(aTitle);
3103 aNewSection.mpTitlePageHdFt = &pDoc->_GetPageDesc(nPageNo);
3104 aNewSection.mbTitlePageHdFtUsed = true;
3105 maSegments.maDummyPageNos.push_back(nPageNo);
3107 ReadHeaderFooter(nToken, aNewSection.mpTitlePageHdFt);
3108 break;
3109 case RTF_COLS:
3110 aNewSection.mnCols = nTokenValue;
3111 break;
3112 case RTF_COLSX:
3113 aNewSection.mnColsx = nTokenValue;
3114 break;
3115 case RTF_COLNO:
3117 // next token must be either colw or colsr
3118 unsigned long nAktCol = nValue;
3119 long nWidth = 0, nSpace = 0;
3120 int nColToken = GetNextToken();
3121 if (RTF_COLW == nColToken)
3123 // next token could be colsr (but not required)
3124 nWidth = nTokenValue;
3125 if( RTF_COLSR == GetNextToken() )
3126 nSpace = nTokenValue;
3127 else
3128 SkipToken( -1 ); // put back token
3130 else if (RTF_COLSR == nColToken)
3132 // next token must be colw (what sense should it make to have colsr only?!)
3133 nSpace = nTokenValue;
3134 if( RTF_COLW == GetNextToken() )
3135 nWidth = nTokenValue;
3136 else
3137 // what should we do if an isolated colsr without colw is found? Doesn't make sense!
3138 SkipToken( -1 ); // put back token
3140 else
3141 break;
3143 if (--nAktCol == (aNewSection.maColumns.size() / 2))
3145 aNewSection.maColumns.push_back(nWidth);
3146 aNewSection.maColumns.push_back(nSpace);
3149 break;
3150 case RTF_STEXTFLOW:
3151 aNewSection.mnStextflow = nTokenValue;
3152 break;
3153 case RTF_RTLSECT:
3154 aNewSection.mbRTLsection = true;
3155 break;
3156 case RTF_LTRSECT:
3157 aNewSection.mbRTLsection = false;
3158 break;
3159 case '{':
3161 short nSkip = 0;
3162 if( RTF_IGNOREFLAG != ( nToken = GetNextToken() ))
3163 nSkip = -1;
3164 else if( RTF_SECTFMT != (( nToken = GetNextToken() )
3165 & ~(0xff | RTF_SWGDEFS)) &&
3166 ( RTF_DOCFMT != ( nToken & ~(0xff | RTF_SWGDEFS))) )
3167 nSkip = -2;
3168 else
3170 // erstmal komplett ueberlesen
3171 SkipGroup();
3172 // ueberlese noch die schliessende Klammer
3173 GetNextToken();
3175 if (nSkip)
3177 bWeiter = ((-1 == nSkip) &&
3179 RTF_FOOTER == nToken || RTF_HEADER == nToken ||
3180 RTF_FOOTERR == nToken || RTF_HEADERR == nToken ||
3181 RTF_FOOTERL == nToken || RTF_HEADERL == nToken ||
3182 RTF_FOOTERF == nToken || RTF_HEADERF == nToken
3184 SkipToken (nSkip); // Ignore wieder zurueck
3187 break;
3188 case RTF_PAPERW:
3189 case RTF_PAPERH:
3190 case RTF_MARGL:
3191 case RTF_MARGR:
3192 case RTF_MARGT:
3193 case RTF_MARGB:
3194 case RTF_FACINGP:
3195 ASSERT(!this, "why are these tokens found in this section?");
3196 ReadDocControls( nToken );
3197 break;
3198 default:
3199 if (RTF_DOCFMT == (nToken & ~(0xff | RTF_SWGDEFS)))
3200 ReadDocControls( nToken );
3201 else if (RTF_SECTFMT == (nToken & ~(0xff | RTF_SWGDEFS)) ||
3202 RTF_UNKNOWNCONTROL == nToken)
3204 SvxRTFParser::NextToken(nToken);
3206 else
3207 bWeiter = false;
3208 break;
3211 if (bWeiter)
3212 nToken = GetNextToken();
3213 } while (bWeiter && IsParserWorking());
3215 if (bNewSection || maSegments.empty())
3217 AttrGroupEnd(); //#106493#
3218 if(!bContainsPara && !bContainsTablePara) //#117881#: bContainsTablePara is set in rtftbl.cxx
3219 pDoc->AppendTxtNode(*pPam->GetPoint());
3220 bContainsPara = false;
3221 bContainsTablePara = false;
3222 maSegments.push_back(rtfSection(*pPam->GetPoint(), aNewSection));
3224 else //modifying/replacing the current section
3226 SwPaM aPamStart(maSegments.back().maStart);
3227 maSegments.pop_back();
3228 maSegments.push_back(rtfSection(*aPamStart.GetPoint(), aNewSection));
3231 SkipToken(-1);
3234 void SwRTFParser::EnterEnvironment()
3239 void SwRTFParser::LeaveEnvironment()
3241 if(pRedlineDelete)
3243 delete pRedlineDelete;
3244 pRedlineDelete = 0;
3247 if(pRedlineInsert)
3249 delete pRedlineInsert;
3250 pRedlineInsert = 0;
3254 void SwRTFParser::SkipPageDescTbl()
3256 // M.M. #117907# I have to use this glorified SkipGroup because the
3257 // SvParser SkipGroup uses nNextCh which is not set correctly <groan>
3258 int nNumOpenBrakets = 1;
3260 while( nNumOpenBrakets && IsParserWorking() )
3262 switch( GetNextToken() )
3264 case '}':
3266 --nNumOpenBrakets;
3268 break;
3270 case '{':
3272 nNumOpenBrakets++;
3274 break;
3278 SkipToken( -1 );
3281 void SwRTFParser::ReadPageDescTbl()
3283 // dann erzeuge aus der SvxStyle-Tabelle die Swg-Collections, damit
3284 // diese auch in den Headers/Footer benutzt werden koennen!
3285 MakeStyleTab();
3286 // das default-Style schon gleich am ersten Node setzen
3287 SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 );
3288 if( !pColl )
3289 pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
3290 pDoc->SetTxtFmtColl( *pPam, pColl );
3292 int nToken, bSaveChkStyleAttr = IsChkStyleAttr();
3293 int nNumOpenBrakets = 1; // die erste wurde schon vorher erkannt !!
3295 SetChkStyleAttr(FALSE); // Attribute nicht gegen die Styles checken
3297 bInPgDscTbl = true;
3298 USHORT nPos = 0;
3299 SwPageDesc* pPg = 0;
3300 SwFrmFmt* pPgFmt = 0;
3302 SvxULSpaceItem aUL( RES_UL_SPACE ), aHUL( RES_UL_SPACE ), aFUL( RES_UL_SPACE );
3303 SvxLRSpaceItem aLR( RES_LR_SPACE ), aHLR( RES_LR_SPACE ), aFLR( RES_LR_SPACE );
3304 Size a4 = SvxPaperInfo::GetPaperSize(PAPER_A4);
3305 SwFmtFrmSize aSz( ATT_FIX_SIZE, a4.Width(), a4.Height() ); // DIN A4 defaulten
3306 SwFmtFrmSize aFSz( ATT_MIN_SIZE ), aHSz( ATT_MIN_SIZE );
3308 SvxFrameDirectionItem aFrmDir(FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR);
3310 USHORT nCols = USHRT_MAX, nColSpace = USHRT_MAX, nAktCol = 0;
3311 SvUShorts aColumns;
3313 while( nNumOpenBrakets && IsParserWorking() )
3315 switch( nToken = GetNextToken() )
3317 case '{':
3318 ++nNumOpenBrakets;
3319 break;
3320 case '}':
3321 if (1 == --nNumOpenBrakets)
3323 ASSERT(pPgFmt && pPg, "Serious problem here");
3324 if (pPgFmt && pPg)
3326 // PageDesc ist fertig, setze am Doc
3327 pPgFmt->SetFmtAttr(aFrmDir);
3328 pPgFmt->SetFmtAttr(aLR);
3329 pPgFmt->SetFmtAttr(aUL);
3330 pPgFmt->SetFmtAttr(aSz);
3331 ::lcl_SetFmtCol(*pPgFmt, nCols, nColSpace, aColumns);
3332 if (pPgFmt->GetHeader().GetHeaderFmt())
3334 SwFrmFmt* pHFmt =
3335 (SwFrmFmt*)pPgFmt->GetHeader().GetHeaderFmt();
3336 pHFmt->SetFmtAttr(aHUL);
3337 pHFmt->SetFmtAttr(aHLR);
3338 pHFmt->SetFmtAttr(aHSz);
3340 if (pPgFmt->GetFooter().GetFooterFmt())
3342 SwFrmFmt* pFFmt =
3343 (SwFrmFmt*)pPgFmt->GetFooter().GetFooterFmt();
3344 pFFmt->SetFmtAttr(aHUL);
3345 pFFmt->SetFmtAttr(aHLR);
3346 pFFmt->SetFmtAttr(aHSz);
3348 if( nPos < pDoc->GetPageDescCnt() )
3349 pDoc->ChgPageDesc(nPos++, *pPg);
3352 break;
3353 case RTF_PGDSC:
3354 if (nPos) // kein && wg MAC
3356 if (nPos != pDoc->MakePageDesc(
3357 String::CreateFromInt32(nTokenValue)))
3359 ASSERT( FALSE, "PageDesc an falscher Position" );
3362 pPg = &pDoc->_GetPageDesc(nPos);
3363 pPg->SetLandscape( FALSE );
3364 pPgFmt = &pPg->GetMaster();
3365 #ifndef CFRONT
3366 SETPAGEDESC_DEFAULTS:
3367 #endif
3368 aSz.SetWidth( a4.Width() ); aSz.SetHeight( a4.Height() );
3369 aLR.SetLeft( 0 ); aLR.SetRight( 0 );
3370 aUL.SetLower( 0 ); aUL.SetUpper( 0 );
3371 aHLR.SetLeft( 0 ); aHLR.SetRight( 0 );
3372 aHUL.SetLower( 0 ); aHUL.SetUpper( 0 );
3373 aFLR.SetLeft( 0 ); aFLR.SetRight( 0 );
3374 aFUL.SetLower( 0 ); aFUL.SetUpper( 0 );
3375 nCols = USHRT_MAX; nColSpace = USHRT_MAX; nAktCol = 0;
3376 aFSz.SetHeightSizeType( ATT_MIN_SIZE ); aFSz.SetHeight( 0 );
3377 aHSz.SetHeightSizeType( ATT_MIN_SIZE ); aHSz.SetHeight( 0 );
3378 break;
3380 case RTF_PGDSCUSE:
3381 pPg->WriteUseOn( (UseOnPage)nTokenValue );
3382 break;
3384 case RTF_PGDSCNXT:
3385 // setze erstmal nur die Nummer als Follow. Am Ende der
3386 // Tabelle wird diese entsprechend korrigiert !!
3387 if( nTokenValue )
3388 pPg->SetFollow( (const SwPageDesc*)nTokenValue );
3389 else
3390 pPg->SetFollow( & const_cast<const SwDoc *>(pDoc)
3391 ->GetPageDesc( 0 ) );
3392 break;
3394 case RTF_FORMULA: /* Zeichen "\|" !!! */
3395 pPgFmt->SetFmtAttr( aLR );
3396 pPgFmt->SetFmtAttr( aUL );
3397 pPgFmt->SetFmtAttr( aSz );
3398 ::lcl_SetFmtCol( *pPgFmt, nCols, nColSpace, aColumns );
3399 if( pPgFmt->GetHeader().GetHeaderFmt() )
3401 SwFrmFmt* pHFmt = (SwFrmFmt*)pPgFmt->GetHeader().GetHeaderFmt();
3402 pHFmt->SetFmtAttr( aHUL );
3403 pHFmt->SetFmtAttr( aHLR );
3404 pHFmt->SetFmtAttr( aHSz );
3406 if( pPgFmt->GetFooter().GetFooterFmt() )
3408 SwFrmFmt* pFFmt = (SwFrmFmt*)pPgFmt->GetFooter().GetFooterFmt();
3409 pFFmt->SetFmtAttr( aHUL );
3410 pFFmt->SetFmtAttr( aHLR );
3411 pFFmt->SetFmtAttr( aHSz );
3414 pPgFmt = &pPg->GetLeft();
3415 #ifndef CFRONT
3416 goto SETPAGEDESC_DEFAULTS;
3417 #else
3418 aLR.SetLeft( 0 ); aLR.SetRight( 0 );
3419 aUL.SetLower( 0 ); aUL.SetUpper( 0 );
3420 aHLR.SetLeft( 0 ); aHLR.SetRight( 0 );
3421 aHUL.SetLower( 0 ); aHUL.SetUpper( 0 );
3422 aFLR.SetLeft( 0 ); aFLR.SetRight( 0 );
3423 aFUL.SetLower( 0 ); aFUL.SetUpper( 0 );
3424 aSz.SetWidth( a4.Width() ); aSz.SetHeight( a4.Height() ); // DIN A4 default
3425 nCols = USHRT_MAX; nColSpace = USHRT_MAX; nAktCol = 0;
3426 aFSz.SetHeightSizeType( ATT_MIN_SIZE ); aFSz.SetHeight( 0 );
3427 aHSz.SetHeightSizeType( ATT_MIN_SIZE ); aHSz.SetHeight( 0 );
3428 break;
3429 #endif
3431 case RTF_RTLSECT:
3432 aFrmDir.SetValue(FRMDIR_HORI_RIGHT_TOP);
3433 break;
3435 case RTF_LTRSECT:
3436 aFrmDir.SetValue(FRMDIR_HORI_LEFT_TOP);
3437 break;
3439 // alt: LI/RI/SA/SB, neu: MARG?SXN
3440 case RTF_MARGLSXN:
3441 case RTF_LI: aLR.SetLeft( (USHORT)nTokenValue ); break;
3442 case RTF_MARGRSXN:
3443 case RTF_RI: aLR.SetRight( (USHORT)nTokenValue ); break;
3444 case RTF_MARGTSXN:
3445 case RTF_SA: aUL.SetUpper( (USHORT)nTokenValue ); break;
3446 case RTF_MARGBSXN:
3447 case RTF_SB: aUL.SetLower( (USHORT)nTokenValue ); break;
3448 case RTF_PGWSXN: aSz.SetWidth( nTokenValue ); break;
3449 case RTF_PGHSXN: aSz.SetHeight( nTokenValue ); break;
3451 case RTF_HEADERY: aHUL.SetUpper( (USHORT)nTokenValue ); break;
3452 case RTF_HEADER_YB: aHUL.SetLower( (USHORT)nTokenValue ); break;
3453 case RTF_HEADER_XL: aHLR.SetLeft( (USHORT)nTokenValue ); break;
3454 case RTF_HEADER_XR: aHLR.SetRight( (USHORT)nTokenValue ); break;
3455 case RTF_FOOTERY: aFUL.SetLower( (USHORT)nTokenValue ); break;
3456 case RTF_FOOTER_YT: aFUL.SetUpper( (USHORT)nTokenValue ); break;
3457 case RTF_FOOTER_XL: aFLR.SetLeft( (USHORT)nTokenValue ); break;
3458 case RTF_FOOTER_XR: aFLR.SetRight( (USHORT)nTokenValue ); break;
3460 case RTF_HEADER_YH:
3461 if( 0 > nTokenValue )
3463 aHSz.SetHeightSizeType( ATT_FIX_SIZE );
3464 nTokenValue = -nTokenValue;
3466 aHSz.SetHeight( (USHORT)nTokenValue );
3467 break;
3469 case RTF_FOOTER_YH:
3470 if( 0 > nTokenValue )
3472 aFSz.SetHeightSizeType( ATT_FIX_SIZE );
3473 nTokenValue = -nTokenValue;
3475 aFSz.SetHeight( (USHORT)nTokenValue );
3476 break;
3479 case RTF_LNDSCPSXN: pPg->SetLandscape( TRUE ); break;
3481 case RTF_COLS: nCols = (USHORT)nTokenValue; break;
3482 case RTF_COLSX: nColSpace = (USHORT)nTokenValue; break;
3484 case RTF_COLNO:
3485 nAktCol = (USHORT)nTokenValue;
3486 if( RTF_COLW == GetNextToken() )
3488 USHORT nWidth = USHORT( nTokenValue ), nSpace = 0;
3489 if( RTF_COLSR == GetNextToken() )
3490 nSpace = USHORT( nTokenValue );
3491 else
3492 SkipToken( -1 ); // wieder zurueck
3494 if( --nAktCol == ( aColumns.Count() / 2 ) )
3496 aColumns.Insert( nWidth, aColumns.Count() );
3497 aColumns.Insert( nSpace, aColumns.Count() );
3500 break;
3502 case RTF_PAGEBB:
3504 pPgFmt->SetFmtAttr( SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK ) );
3506 break;
3508 case RTF_HEADER:
3509 case RTF_HEADERL:
3510 case RTF_HEADERR:
3511 case RTF_FOOTER:
3512 case RTF_FOOTERL:
3513 case RTF_FOOTERR:
3514 case RTF_FOOTERF:
3515 case RTF_HEADERF:
3516 ReadHeaderFooter(nToken, pPg);
3517 --nNumOpenBrakets; // Klammer wird im ReadAttr ueberlesen!
3518 break;
3519 case RTF_TEXTTOKEN:
3520 if (!DelCharAtEnd(aToken, ';' ).Len())
3521 break;
3522 ASSERT(pPg, "Unexpected missing pPg");
3523 if (pPg)
3525 pPg->SetName(aToken);
3527 // sollte es eine Vorlage aus dem Pool sein ??
3528 USHORT n = SwStyleNameMapper::GetPoolIdFromUIName(aToken,
3529 nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC);
3530 if (USHRT_MAX != n)
3532 // dann setze bei der Neuen die entsp. PoolId
3533 pPg->SetPoolFmtId(n);
3536 break;
3537 case RTF_BRDBOX:
3538 if (3 == nNumOpenBrakets)
3540 ReadBorderAttr(SkipToken(-2),
3541 (SfxItemSet&)pPgFmt->GetAttrSet());
3542 --nNumOpenBrakets; // Klammer wird im ReadAttr ueberlesen!
3544 break;
3545 case RTF_SHADOW:
3546 if( 3 == nNumOpenBrakets )
3548 ReadAttr( SkipToken( -2 ), (SfxItemSet*)&pPgFmt->GetAttrSet() );
3549 --nNumOpenBrakets; // Klammer wird im ReadAttr ueberlesen!
3551 break;
3554 default:
3555 if( (nToken & ~0xff ) == RTF_SHADINGDEF )
3556 ReadBackgroundAttr( nToken, (SfxItemSet&)pPgFmt->GetAttrSet() );
3557 break;
3562 // setze jetzt noch bei allen die entsprechenden Follows !!
3563 // Die, die ueber die Tabelle eingelesen wurden und einen
3564 // Follow definiert haben, ist dieser als Tabposition im
3565 // Follow schon gesetzt.
3566 for( nPos = 0; nPos < pDoc->GetPageDescCnt(); ++nPos )
3568 SwPageDesc* pPgDsc = &pDoc->_GetPageDesc( nPos );
3569 if( (USHORT)(long)pPgDsc->GetFollow() < pDoc->GetPageDescCnt() )
3570 pPgDsc->SetFollow(& const_cast<const SwDoc *>(pDoc)
3571 ->GetPageDesc((USHORT)(long)
3572 pPgDsc->GetFollow()));
3575 SetChkStyleAttr( bSaveChkStyleAttr );
3577 bInPgDscTbl = false;
3578 nAktPageDesc = 0;
3579 nAktFirstPageDesc = 0;
3580 bSwPageDesc = true;
3581 SkipToken( -1 );
3584 // -------------- Methoden --------------------
3587 void SwRTFParser::ReadUnknownData()
3589 SvRTFParser::ReadUnknownData();
3592 void SwRTFParser::ReadOLEData()
3594 SvRTFParser::ReadOLEData();
3598 void SwRTFParser::ReadPrtData()
3600 while( IsParserWorking() )
3602 int nToken = GetNextToken();
3603 if( (RTF_TEXTTOKEN != nToken) && ('}' == nToken) )
3604 break;
3607 SkipToken( -1 ); // schliessende Klammer wieder zurueck!!
3610 static const SwNodeIndex* SetHeader(SwFrmFmt* pHdFtFmt, BOOL bReuseOld)
3612 ASSERT(pHdFtFmt, "Impossible, no header");
3613 const SwFrmFmt* pExisting = bReuseOld ?
3614 pHdFtFmt->GetHeader().GetHeaderFmt() : 0;
3615 if (!pExisting)
3617 //No existing header, create a new one
3618 pHdFtFmt->SetFmtAttr(SwFmtHeader(TRUE));
3619 pExisting = pHdFtFmt->GetHeader().GetHeaderFmt();
3621 return pExisting->GetCntnt().GetCntntIdx();
3624 static const SwNodeIndex* SetFooter(SwFrmFmt* pHdFtFmt, BOOL bReuseOld)
3626 ASSERT(pHdFtFmt, "Impossible, no footer");
3627 const SwFrmFmt* pExisting = bReuseOld ?
3628 pHdFtFmt->GetFooter().GetFooterFmt() : 0;
3629 if (!pExisting)
3631 //No exist footer, create a new one
3632 pHdFtFmt->SetFmtAttr(SwFmtFooter(TRUE));
3633 pExisting = pHdFtFmt->GetFooter().GetFooterFmt();
3635 return pExisting->GetCntnt().GetCntntIdx();
3639 void SwRTFParser::ReadHeaderFooter( int nToken, SwPageDesc* pPageDesc )
3641 ASSERT( RTF_FOOTNOTE == nToken ||
3642 RTF_FLY_INPARA == nToken ||
3643 pPageDesc, "PageDesc fehlt" );
3645 bool bContainsParaCache = bContainsPara;
3646 // alle wichtigen Sachen sichern
3647 SwPosition aSavePos( *pPam->GetPoint() );
3648 SvxRTFItemStack aSaveStack;
3649 aSaveStack.Insert( &GetAttrStack(), 0 );
3650 GetAttrStack().Remove( 0, GetAttrStack().Count() );
3652 // save the fly array - after read, all flys may be set into
3653 // the header/footer
3654 SwFlySaveArr aSaveArray( 255 < aFlyArr.Count() ? aFlyArr.Count() : 255 );
3655 aSaveArray.Insert( &aFlyArr, 0 );
3656 aFlyArr.Remove( 0, aFlyArr.Count() );
3657 BOOL bSetFlyInDoc = TRUE;
3659 const SwNodeIndex* pSttIdx = 0;
3660 SwFrmFmt* pHdFtFmt = 0;
3661 SwTxtAttr* pTxtAttr = 0;
3662 int bDelFirstChar = FALSE;
3663 bool bOldIsFootnote = mbIsFootnote;
3664 BOOL bOldGrpStt = sal::static_int_cast< BOOL, int >(IsNewGroup());
3666 int nNumOpenBrakets = GetOpenBrakets() - 1;
3668 switch( nToken )
3670 case RTF_FOOTNOTE:
3672 bool bIsEndNote = RTF_FTNALT == GetNextToken();
3673 if (!bIsEndNote)
3674 SkipToken(-1);
3676 SwTxtNode* pTxtNd = pPam->GetNode()->GetTxtNode();
3677 SwFmtFtn aFtnNote(bIsEndNote);
3678 xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex();
3680 if (nPos && !bFootnoteAutoNum)
3682 pPam->GetPoint()->nContent--;
3683 nPos--;
3684 aFtnNote.SetNumStr( pTxtNd->GetTxt().GetChar( nPos ) );
3685 ((String&)pTxtNd->GetTxt()).SetChar( nPos, CH_TXTATR_INWORD );
3686 bDelFirstChar = TRUE;
3689 pTxtAttr = pTxtNd->InsertItem( aFtnNote, nPos, nPos,
3690 bDelFirstChar ? nsSetAttrMode::SETATTR_NOTXTATRCHR : 0 );
3692 ASSERT( pTxtAttr, "konnte die Fussnote nicht einfuegen/finden" );
3694 if( pTxtAttr )
3695 pSttIdx = ((SwTxtFtn*)pTxtAttr)->GetStartNode();
3696 mbIsFootnote = true;
3698 // wurde an der Position ein Escapement aufgespannt, so entferne
3699 // das jetzt. Fussnoten sind bei uns immer hochgestellt.
3700 SvxRTFItemStackTypePtr pTmp = aSaveStack.Top();
3701 if( pTmp && pTmp->GetSttNodeIdx() ==
3702 pPam->GetPoint()->nNode.GetIndex() &&
3703 pTmp->GetSttCnt() == nPos )
3704 pTmp->GetAttrSet().ClearItem( RES_CHRATR_ESCAPEMENT );
3706 break;
3708 case RTF_FLY_INPARA:
3710 xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex();
3711 SfxItemSet aSet( pDoc->GetAttrPool(), RES_FRMATR_BEGIN,
3712 RES_FRMATR_END-1 );
3713 aSet.Put( SwFmtAnchor( FLY_IN_CNTNT ));
3714 pHdFtFmt = pDoc->MakeFlySection( FLY_IN_CNTNT, pPam->GetPoint(), &aSet );
3716 pTxtAttr = pPam->GetNode()->GetTxtNode()->GetTxtAttrForCharAt(
3717 nPos, RES_TXTATR_FLYCNT );
3718 ASSERT( pTxtAttr, "konnte den Fly nicht einfuegen/finden" );
3720 pSttIdx = pHdFtFmt->GetCntnt().GetCntntIdx();
3721 bSetFlyInDoc = FALSE;
3723 break;
3725 case RTF_HEADERF:
3726 case RTF_HEADER:
3727 pPageDesc->WriteUseOn( (UseOnPage)(pPageDesc->ReadUseOn() | nsUseOnPage::PD_HEADERSHARE) );
3728 pHdFtFmt = &pPageDesc->GetMaster();
3729 pSttIdx = SetHeader( pHdFtFmt, FALSE );
3730 break;
3732 case RTF_HEADERL:
3733 // we cannot have left or right, must have always both
3734 pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_HEADERSHARE) | nsUseOnPage::PD_ALL));
3735 SetHeader( pPageDesc->GetRightFmt(), TRUE );
3736 pHdFtFmt = pPageDesc->GetLeftFmt();
3737 pSttIdx = SetHeader(pHdFtFmt, FALSE );
3738 break;
3740 case RTF_HEADERR:
3741 // we cannot have left or right, must have always both
3742 pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_HEADERSHARE) | nsUseOnPage::PD_ALL));
3743 SetHeader( pPageDesc->GetLeftFmt(), TRUE );
3744 pHdFtFmt = pPageDesc->GetRightFmt();
3745 pSttIdx = SetHeader(pHdFtFmt, FALSE );
3746 break;
3748 case RTF_FOOTERF:
3749 case RTF_FOOTER:
3750 pPageDesc->WriteUseOn( (UseOnPage)(pPageDesc->ReadUseOn() | nsUseOnPage::PD_FOOTERSHARE) );
3751 pHdFtFmt = &pPageDesc->GetMaster();
3752 pSttIdx = SetFooter(pHdFtFmt, FALSE );
3753 break;
3755 case RTF_FOOTERL:
3756 // we cannot have left or right, must have always both
3757 pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_FOOTERSHARE) | nsUseOnPage::PD_ALL));
3758 SetFooter( pPageDesc->GetRightFmt(), TRUE );
3759 pHdFtFmt = pPageDesc->GetLeftFmt();
3760 pSttIdx = SetFooter(pHdFtFmt, FALSE );
3761 break;
3763 case RTF_FOOTERR:
3764 // we cannot have left or right, must have always both
3765 pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_FOOTERSHARE) | nsUseOnPage::PD_ALL));
3766 SetFooter( pPageDesc->GetLeftFmt(), TRUE );
3767 pHdFtFmt = pPageDesc->GetRightFmt();
3768 pSttIdx = SetFooter(pHdFtFmt, FALSE );
3769 break;
3772 USHORT nOldFlyArrCnt = aFlyArr.Count();
3773 if( !pSttIdx )
3774 SkipGroup();
3775 else
3777 // es ist auf jedenfall jetzt ein TextNode im Kopf/Fusszeilen-Bereich
3778 // vorhanden. Dieser muss jetzt nur noch gefunden und der neue Cursor
3779 // dort hinein gesetzt werden.
3780 SwCntntNode *pNode = pDoc->GetNodes()[ pSttIdx->GetIndex()+1 ]->
3781 GetCntntNode();
3783 // immer ans Ende der Section einfuegen !!
3784 pPam->GetPoint()->nNode = *pNode->EndOfSectionNode();
3785 pPam->Move( fnMoveBackward );
3787 SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 );
3788 if( !pColl )
3789 pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
3790 pDoc->SetTxtFmtColl( *pPam, pColl );
3792 SetNewGroup( TRUE );
3794 while( !( nNumOpenBrakets == GetOpenBrakets() && !GetStackPos()) && IsParserWorking() )
3796 switch( nToken = GetNextToken() )
3798 case RTF_U:
3799 if( bDelFirstChar )
3801 bDelFirstChar = FALSE;
3802 nToken = 0;
3804 break;
3806 case RTF_TEXTTOKEN:
3807 if( bDelFirstChar )
3809 if( !aToken.Erase( 0, 1 ).Len() )
3810 nToken = 0;
3811 bDelFirstChar = FALSE;
3813 break;
3815 if( nToken )
3816 NextToken( nToken );
3819 SetAllAttrOfStk();
3820 if( aFlyArr.Count() && bSetFlyInDoc )
3821 SetFlysInDoc();
3823 // sollte der letze Node leer sein, dann loesche ihn
3824 // (\par heisst ja Absatzende und nicht neuer Absatz!)
3825 DelLastNode();
3828 // vom FlyFmt noch die richtigen Attribute setzen
3829 if( pTxtAttr && RES_TXTATR_FLYCNT == pTxtAttr->Which() )
3831 // is add a new fly ?
3832 if( nOldFlyArrCnt < aFlyArr.Count() )
3834 SwFlySave* pFlySave = aFlyArr[ aFlyArr.Count()-1 ];
3835 pFlySave->aFlySet.ClearItem( RES_ANCHOR );
3836 pHdFtFmt->SetFmtAttr( pFlySave->aFlySet );
3837 aFlyArr.DeleteAndDestroy( aFlyArr.Count() - 1 );
3839 else
3841 // no, so remove the created textattribute
3842 SwFrmFmt* pFlyFmt = pTxtAttr->GetFlyCnt().GetFrmFmt();
3843 // remove the pam from the flynode
3844 *pPam->GetPoint() = aSavePos;
3845 pDoc->DelLayoutFmt( pFlyFmt );
3849 bFootnoteAutoNum = FALSE; // default auf aus!
3851 // und alles wieder zurueck
3852 *pPam->GetPoint() = aSavePos;
3853 if (mbIsFootnote)
3854 SetNewGroup( bOldGrpStt ); // Status wieder zurueck
3855 else
3856 SetNewGroup( FALSE ); // { - Klammer war kein Group-Start!
3857 mbIsFootnote = bOldIsFootnote;
3858 GetAttrStack().Insert( &aSaveStack, 0 );
3860 aFlyArr.Insert( &aSaveArray, 0 );
3861 aSaveArray.Remove( 0, aSaveArray.Count() );
3862 bContainsPara = bContainsParaCache;
3865 void SwRTFParser::SetSwgValues( SfxItemSet& rSet )
3867 const SfxPoolItem* pItem;
3868 // Escapement korrigieren
3869 if( SFX_ITEM_SET == rSet.GetItemState( RES_CHRATR_ESCAPEMENT, FALSE, &pItem ))
3871 /* prozentuale Veraenderung errechnen !
3872 * Formel : (FontSize * 1/20 ) pts Escapement * 2
3873 * ----------------------- = ----------------
3874 * 100% x
3877 // die richtige
3878 long nEsc = ((SvxEscapementItem*)pItem)->GetEsc();
3880 // automatische Ausrichtung wurde schon richtig berechnet
3881 if( DFLT_ESC_AUTO_SUPER != nEsc && DFLT_ESC_AUTO_SUB != nEsc )
3883 const SvxFontHeightItem& rFH = GetSize( rSet );
3884 nEsc *= 1000L;
3885 if(rFH.GetHeight()) nEsc /= long(rFH.GetHeight()); // #i77256#
3887 SvxEscapementItem aEsc( (short) nEsc,
3888 ((SvxEscapementItem*)pItem)->GetProp(), RES_CHRATR_ESCAPEMENT);
3889 rSet.Put( aEsc );
3893 // TabStops anpassen
3894 if( SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_TABSTOP, FALSE, &pItem ))
3896 const SvxLRSpaceItem& rLR = GetLRSpace( rSet );
3897 SvxTabStopItem aTStop( *(SvxTabStopItem*)pItem );
3899 long nOffset = rLR.GetTxtLeft();
3900 if( nOffset )
3902 // Tabs anpassen !!
3903 SvxTabStop* pTabs = (SvxTabStop*)aTStop.GetStart();
3904 for( USHORT n = aTStop.Count(); n; --n, ++pTabs)
3905 if( SVX_TAB_ADJUST_DEFAULT != pTabs->GetAdjustment() )
3906 pTabs->GetTabPos() -= nOffset;
3908 // negativer Einzug, dann auf 0 Pos einen Tab setzen
3909 if( rLR.GetTxtFirstLineOfst() < 0 )
3910 aTStop.Insert( SvxTabStop() );
3913 if( !aTStop.Count() )
3915 const SvxTabStopItem& rDflt = (const SvxTabStopItem&)rSet.
3916 GetPool()->GetDefaultItem(RES_PARATR_TABSTOP);
3917 if( rDflt.Count() )
3918 aTStop.Insert( &rDflt, 0 );
3920 rSet.Put( aTStop );
3922 else if( SFX_ITEM_SET == rSet.GetItemState( RES_LR_SPACE, FALSE, &pItem )
3923 && ((SvxLRSpaceItem*)pItem)->GetTxtFirstLineOfst() < 0 )
3925 // negativer Einzug, dann auf 0 Pos einen Tab setzen
3926 rSet.Put( SvxTabStopItem( 1, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP ));
3929 // NumRules anpassen
3930 if( !bStyleTabValid &&
3931 SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_NUMRULE, FALSE, &pItem ))
3933 // dann steht im Namen nur ein Verweis in das ListArray
3934 SwNumRule* pRule = GetNumRuleOfListNo( ((SwNumRuleItem*)pItem)->
3935 GetValue().ToInt32() );
3936 if( pRule )
3937 rSet.Put( SwNumRuleItem( pRule->GetName() ));
3938 else
3939 rSet.ClearItem( RES_PARATR_NUMRULE );
3945 ????????????????????????????????????????????????????????????????????
3946 ?? muss die LineSpacing Hoehe 200Twip betragen ??
3947 ?? in rtfitem.hxx wird es auf 0 defaultet. Wenn ja, dann muss hier
3948 ?? ein neues Item gesetzt werden!!!!
3949 ????????????????????????????????????????????????????????????????????
3951 // LineSpacing korrigieren
3952 if( SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_LINESPACING, FALSE, &pItem ))
3954 const SvxLineSpacingItem* pLS = (const SvxLineSpacingItem*)pItem;
3955 SvxLineSpacingItem aNew;
3957 aNew.SetInterLineSpace( pLS->GetInterLineSpace() );
3958 aNew.GetLineSpaceRule() = pLS->GetLineSpaceRule();
3959 aNew.SetPropLineSpace( pLS->GetPropLineSpace() );
3960 aNew.GetInterLineSpaceRule() = pLS->GetInterLineSpaceRule();
3962 rSet.Put( aNew );
3964 ?????????????????????????????????????????????????????????????????? */
3969 SwTxtFmtColl* SwRTFParser::MakeColl(const String& rName, USHORT nPos,
3970 BYTE nOutlineLevel, bool& rbCollExist)
3972 if( BYTE(-1) == nOutlineLevel )
3973 //nOutlineLevel = NO_NUMBERING;
3974 nOutlineLevel = MAXLEVEL;//#outline level,zhaojianwei
3976 rbCollExist = false;
3977 SwTxtFmtColl* pColl;
3978 String aNm( rName );
3979 if( !aNm.Len() )
3981 ASSERT(!this, "not a bug, but I (cmc) want to see an example of this");
3982 if( !nPos )
3984 pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
3985 //pColl->SetOutlineLevel( nOutlineLevel ); //#outline level,removed by zhaojianwei
3986 if(nOutlineLevel < MAXLEVEL ) //->add by zhaojianwei
3987 pColl->AssignToListLevelOfOutlineStyle( nOutlineLevel );
3988 else
3989 pColl->DeleteAssignmentToListLevelOfOutlineStyle(); //<-end,zhaojianwei
3990 return pColl;
3993 // erzeuge einen Namen
3994 aNm.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NoName(" ));
3995 aNm += String::CreateFromInt32( nPos );
3996 aNm += ')';
3998 ww::sti eSti = ww::GetCanonicalStiFromEnglishName(rName);
3999 sw::util::ParaStyleMapper::StyleResult aResult =
4000 maParaStyleMapper.GetStyle(rName, eSti);
4001 pColl = aResult.first;
4002 rbCollExist = aResult.second;
4003 if (IsNewDoc() && rbCollExist)
4005 // --> OD 2007-01-25 #i73790# - method renamed
4006 pColl->ResetAllFmtAttr();
4007 // <--
4008 rbCollExist = false;
4011 if (!rbCollExist)
4013 //pColl->SetOutlineLevel( nOutlineLevel ); //#outline level,removed by zhaojianwei
4014 if(nOutlineLevel < MAXLEVEL) //->add by zhaojianwei
4015 pColl->AssignToListLevelOfOutlineStyle( nOutlineLevel );
4016 else
4017 pColl->DeleteAssignmentToListLevelOfOutlineStyle(); //<-end,zhaojianwei
4020 return pColl;
4023 SwCharFmt* SwRTFParser::MakeCharFmt(const String& rName, USHORT nPos,
4024 int& rbCollExist)
4026 rbCollExist = FALSE;
4027 SwCharFmt* pFmt;
4028 String aNm( rName );
4029 if( !aNm.Len() )
4031 ASSERT(!this, "not a bug, but I (cmc) want to see an example of this");
4032 aNm.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NoName(" ));
4033 aNm += String::CreateFromInt32( nPos );
4034 aNm += ')';
4037 ww::sti eSti = ww::GetCanonicalStiFromEnglishName(rName);
4038 sw::util::CharStyleMapper::StyleResult aResult =
4039 maCharStyleMapper.GetStyle(rName, eSti);
4040 pFmt = aResult.first;
4041 rbCollExist = aResult.second;
4042 if (IsNewDoc() && rbCollExist)
4044 // --> OD 2007-01-25 #i73790# - method renamed
4045 pFmt->ResetAllFmtAttr();
4046 // <--
4047 rbCollExist = false;
4049 return pFmt;
4052 void SwRTFParser::SetStyleAttr( SfxItemSet& rCollSet,
4053 const SfxItemSet& rStyleSet,
4054 const SfxItemSet& rDerivedSet )
4056 rCollSet.Put( rStyleSet );
4057 if( rDerivedSet.Count() )
4059 // suche alle Attribute, die neu gesetzt werden:
4060 const SfxPoolItem* pItem;
4061 SfxItemIter aIter( rDerivedSet );
4062 USHORT nWhich = aIter.GetCurItem()->Which();
4063 while( TRUE )
4065 switch( rStyleSet.GetItemState( nWhich, FALSE, &pItem ) )
4067 case SFX_ITEM_DEFAULT:
4068 // auf default zuruecksetzen
4069 if( RES_FRMATR_END > nWhich )
4070 rCollSet.Put( rCollSet.GetPool()->GetDefaultItem( nWhich ));
4071 break;
4072 case SFX_ITEM_SET:
4073 if( *pItem == *aIter.GetCurItem() ) // gleiches Attribut?
4074 // definition kommt aus dem Parent
4075 rCollSet.ClearItem( nWhich ); // loeschen
4076 break;
4079 if( aIter.IsAtEnd() )
4080 break;
4081 nWhich = aIter.NextItem()->Which();
4084 // und jetzt noch auf unsere Werte abgleichen
4085 SetSwgValues( rCollSet );
4088 SwTxtFmtColl* SwRTFParser::MakeStyle( USHORT nNo, const SvxRTFStyleType& rStyle)
4090 bool bCollExist;
4091 SwTxtFmtColl* pColl = MakeColl( rStyle.sName, USHORT(nNo),
4092 rStyle.nOutlineNo, bCollExist);
4093 aTxtCollTbl.Insert( nNo, pColl );
4095 // in bestehendes Dok einfuegen, dann keine Ableitung usw. setzen
4096 if( bCollExist )
4097 return pColl;
4099 USHORT nStyleNo = rStyle.nBasedOn;
4100 if( rStyle.bBasedOnIsSet && nStyleNo != nNo )
4102 SvxRTFStyleType* pDerivedStyle = GetStyleTbl().Get( nStyleNo );
4103 SwTxtFmtColl* pDerivedColl = aTxtCollTbl.Get( nStyleNo );
4104 if( !pDerivedColl ) // noch nicht vorhanden, also anlegen
4106 // ist die ueberhaupt als Style vorhanden ?
4107 pDerivedColl = pDerivedStyle
4108 ? MakeStyle( nStyleNo, *pDerivedStyle )
4109 : pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
4112 if( pColl == pDerivedColl )
4113 ((SfxItemSet&)pColl->GetAttrSet()).Put( rStyle.aAttrSet );
4114 else
4116 pColl->SetDerivedFrom( pDerivedColl );
4118 // setze die richtigen Attribute
4119 const SfxItemSet* pDerivedSet;
4120 if( pDerivedStyle )
4121 pDerivedSet = &pDerivedStyle->aAttrSet;
4122 else
4123 pDerivedSet = &pDerivedColl->GetAttrSet();
4125 SetStyleAttr( (SfxItemSet&)pColl->GetAttrSet(),
4126 rStyle.aAttrSet, *pDerivedSet );
4129 else
4130 ((SfxItemSet&)pColl->GetAttrSet()).Put( rStyle.aAttrSet );
4133 nStyleNo = rStyle.nNext;
4134 if( nStyleNo != nNo )
4136 SwTxtFmtColl* pNext = aTxtCollTbl.Get( nStyleNo );
4137 if( !pNext ) // noch nicht vorhanden, also anlegen
4139 // ist die ueberhaupt als Style vorhanden ?
4140 SvxRTFStyleType* pMkStyle = GetStyleTbl().Get( nStyleNo );
4141 pNext = pMkStyle
4142 ? MakeStyle( nStyleNo, *pMkStyle )
4143 : pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
4145 pColl->SetNextTxtFmtColl( *pNext );
4147 return pColl;
4150 SwCharFmt* SwRTFParser::MakeCharStyle( USHORT nNo, const SvxRTFStyleType& rStyle )
4152 int bCollExist;
4153 SwCharFmt* pFmt = MakeCharFmt( rStyle.sName, USHORT(nNo), bCollExist );
4154 aCharFmtTbl.Insert( nNo, pFmt );
4156 // in bestehendes Dok einfuegen, dann keine Ableitung usw. setzen
4157 if( bCollExist )
4158 return pFmt;
4160 USHORT nStyleNo = rStyle.nBasedOn;
4161 if( rStyle.bBasedOnIsSet && nStyleNo != nNo )
4163 SvxRTFStyleType* pDerivedStyle = GetStyleTbl().Get( nStyleNo );
4164 SwCharFmt* pDerivedFmt = aCharFmtTbl.Get( nStyleNo );
4165 if( !pDerivedFmt ) // noch nicht vorhanden, also anlegen
4167 // ist die ueberhaupt als Style vorhanden ?
4168 pDerivedFmt = pDerivedStyle
4169 ? MakeCharStyle( nStyleNo, *pDerivedStyle )
4170 : pDoc->GetDfltCharFmt();
4173 if( pFmt == pDerivedFmt )
4174 ((SfxItemSet&)pFmt->GetAttrSet()).Put( rStyle.aAttrSet );
4175 else
4177 pFmt->SetDerivedFrom( pDerivedFmt );
4179 // setze die richtigen Attribute
4180 const SfxItemSet* pDerivedSet;
4181 if( pDerivedStyle )
4182 pDerivedSet = &pDerivedStyle->aAttrSet;
4183 else
4184 pDerivedSet = &pDerivedFmt->GetAttrSet();
4186 SetStyleAttr( (SfxItemSet&)pFmt->GetAttrSet(),
4187 rStyle.aAttrSet, *pDerivedSet );
4190 else
4191 ((SfxItemSet&)pFmt->GetAttrSet()).Put( rStyle.aAttrSet );
4193 return pFmt;
4196 // loesche den letzten Node (Tabelle/Fly/Ftn/..)
4197 void SwRTFParser::DelLastNode()
4199 // sollte der letze Node leer sein, dann loesche ihn
4200 // (\par heisst ja Absatzende und nicht neuer Absatz!)
4202 if( !pPam->GetPoint()->nContent.GetIndex() )
4204 ULONG nNodeIdx = pPam->GetPoint()->nNode.GetIndex();
4205 SwCntntNode* pCNd = pDoc->GetNodes()[ nNodeIdx ]->GetCntntNode();
4206 // paragraphs with page break information are not empty! see #117914# topic 1)
4207 if(const SfxPoolItem* pItem=&(pCNd->GetAttr( RES_PAGEDESC, FALSE)))
4209 SwFmtPageDesc* pPageDescItem = ((SwFmtPageDesc*)pItem);
4210 if (pPageDescItem->GetPageDesc()!=NULL)
4211 return;
4214 if( pCNd && pCNd->StartOfSectionIndex()+2 <
4215 pCNd->EndOfSectionIndex() )
4217 if( GetAttrStack().Count() )
4219 // Attribut Stack-Eintraege, muessen ans Ende des vorherigen
4220 // Nodes verschoben werden.
4221 BOOL bMove = FALSE;
4222 for( USHORT n = GetAttrStack().Count(); n; )
4224 SvxRTFItemStackType* pStkEntry = (SvxRTFItemStackType*)
4225 GetAttrStack()[ --n ];
4226 if( nNodeIdx == pStkEntry->GetSttNode().GetIdx() )
4228 if( !bMove )
4230 pPam->Move( fnMoveBackward );
4231 bMove = TRUE;
4233 pStkEntry->SetStartPos( SwxPosition( pPam ) );
4236 if( bMove )
4237 pPam->Move( fnMoveForward );
4239 pPam->GetPoint()->nContent.Assign( 0, 0 );
4240 pPam->SetMark();
4241 pPam->DeleteMark();
4243 pDoc->GetNodes().Delete( pPam->GetPoint()->nNode );
4248 // fuer Tokens, die im ReadAttr nicht ausgewertet werden
4249 void SwRTFParser::UnknownAttrToken( int nToken, SfxItemSet* pSet )
4251 switch( nToken )
4253 case RTF_INTBL:
4255 if( !pTableNode ) // Tabelle nicht mehr vorhanden ?
4256 NewTblLine(); // evt. Line copieren
4257 else
4259 static int _do=0; //$flr See #117881# for explanation.
4260 // Crsr nicht mehr in der Tabelle ?
4261 if( !pPam->GetNode()->FindTableNode() && _do )
4263 ULONG nOldPos = pPam->GetPoint()->nNode.GetIndex();
4265 // dann wieder in die letzte Box setzen
4266 // (kann durch einlesen von Flys geschehen!)
4267 pPam->GetPoint()->nNode = *pTableNode->EndOfSectionNode();
4268 pPam->Move( fnMoveBackward );
4270 // alle Attribute, die schon auf den nachfolgen zeigen
4271 // auf die neue Box umsetzen !!
4272 SvxRTFItemStack& rAttrStk = GetAttrStack();
4273 const SvxRTFItemStackType* pStk;
4274 for( USHORT n = 0; n < rAttrStk.Count(); ++n )
4275 if( ( pStk = rAttrStk[ n ])->GetSttNodeIdx() == nOldPos &&
4276 !pStk->GetSttCnt() )
4277 ((SvxRTFItemStackType*)pStk)->SetStartPos( SwxPosition( pPam ) );
4281 break;
4283 case RTF_PAGEBB:
4285 pSet->Put( SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK ));
4287 break;
4289 case RTF_PGBRK:
4291 pSet->Put( SvxFmtBreakItem( 1 == nTokenValue ?
4292 SVX_BREAK_PAGE_BOTH : SVX_BREAK_PAGE_AFTER, RES_BREAK ));
4294 break;
4296 case RTF_PGDSCNO:
4297 if( IsNewDoc() && bSwPageDesc &&
4298 USHORT(nTokenValue) < pDoc->GetPageDescCnt() )
4300 const SwPageDesc* pPgDsc = &const_cast<const SwDoc *>(pDoc)
4301 ->GetPageDesc( (USHORT)nTokenValue );
4302 pDoc->InsertPoolItem( *pPam, SwFmtPageDesc( pPgDsc ), 0);
4304 break;
4305 case RTF_CS:
4307 SwCharFmt* pFmt = aCharFmtTbl.Get( nTokenValue );
4308 if( pFmt )
4309 pSet->Put( SwFmtCharFmt( pFmt ));
4311 break;
4313 case RTF_LS:
4314 if( -1 != nTokenValue )
4316 if( bStyleTabValid )
4318 // dann ist auch die ListTabelle gueltig, also suche die
4319 // enstprechende NumRule
4320 SwNumRule* pRule = GetNumRuleOfListNo( nTokenValue );
4321 if( pRule )
4322 pSet->Put( SwNumRuleItem( pRule->GetName() ));
4324 if( SFX_ITEM_SET != pSet->GetItemState( FN_PARAM_NUM_LEVEL, FALSE ))
4325 pSet->Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 ));
4327 else
4329 // wir sind in der Style-Definitions - Phase. Der Name
4330 // wird dann spaeter umgesetzt
4331 //#117891# pSet->Put( SwNumRuleItem( String::CreateFromInt32( nTokenValue )));
4335 break;
4337 case RTF_ILVL:
4338 case RTF_SOUTLVL:
4340 BYTE nLevel = MAXLEVEL <= nTokenValue ? MAXLEVEL - 1
4341 : BYTE( nTokenValue );
4342 pSet->Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, nLevel ));
4344 break;
4347 case RTF_SBYS:
4348 case RTF_EXPND:
4349 case RTF_KEEP:
4350 case RTF_KEEPN:
4356 void SwRTFParser::ReadInfo( const sal_Char* pChkForVerNo )
4358 sal_Char __READONLY_DATA aChkForVerNo[] = "StarWriter";
4360 // falls nicht schon was vorgegeben wurde, setzen wir unseren Namen
4361 // rein. Wenn das im Kommentar match, wird im Parser die VersionNummer
4362 // gelesen und gesetzt
4363 if( !pChkForVerNo )
4364 pChkForVerNo = aChkForVerNo;
4366 SvxRTFParser::ReadInfo( pChkForVerNo );
4369 void SwRTFParser::ReadUserProperties()
4371 // For now we don't support user properties but at least the parser is here.
4372 // At the moment it just swallows the tokens to prevent them being displayed
4373 int nNumOpenBrakets = 1, nToken;
4375 while( nNumOpenBrakets && IsParserWorking() )
4377 switch( nToken = GetNextToken() )
4379 case '}':
4380 --nNumOpenBrakets;
4381 break;
4382 case '{':
4384 if( RTF_IGNOREFLAG != GetNextToken() )
4385 nToken = SkipToken( -1 );
4386 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
4387 nToken = SkipToken( -2 );
4388 else
4390 // gleich herausfiltern
4391 ReadUnknownData();
4392 nToken = GetNextToken();
4393 if( '}' != nToken )
4394 eState = SVPAR_ERROR;
4395 break;
4397 ++nNumOpenBrakets;
4399 break;
4401 case RTF_PROPNAME:
4402 SkipGroup();
4403 break;
4405 case RTF_PROPTYPE:
4406 break;
4408 case RTF_STATICVAL:
4409 SkipGroup();
4410 break;
4412 // default:
4416 SkipToken( -1 );
4420 #ifdef USED
4421 void SwRTFParser::SaveState( int nToken )
4423 SvxRTFParser::SaveState( nToken );
4426 void SwRTFParser::RestoreState()
4428 SvxRTFParser::RestoreState();
4430 #endif
4432 /*\f*/
4434 BookmarkPosition::BookmarkPosition(const SwPaM &rPaM)
4435 : maMkNode(rPaM.GetMark()->nNode),
4436 mnMkCntnt(rPaM.GetMark()->nContent.GetIndex())
4440 BookmarkPosition::BookmarkPosition(const BookmarkPosition &rEntry)
4441 : maMkNode(rEntry.maMkNode), mnMkCntnt(rEntry.mnMkCntnt)
4445 bool BookmarkPosition::operator==(const BookmarkPosition rhs)
4447 return(maMkNode.GetIndex() == rhs.maMkNode.GetIndex() && mnMkCntnt == rhs.mnMkCntnt);
4450 ULONG SwNodeIdx::GetIdx() const
4452 return aIdx.GetIndex();
4455 SvxNodeIdx* SwNodeIdx::Clone() const
4457 return new SwNodeIdx( aIdx );
4460 SvxPosition* SwxPosition::Clone() const
4462 return new SwxPosition( pPam );
4465 SvxNodeIdx* SwxPosition::MakeNodeIdx() const
4467 return new SwNodeIdx( pPam->GetPoint()->nNode );
4470 ULONG SwxPosition::GetNodeIdx() const
4472 return pPam->GetPoint()->nNode.GetIndex();
4475 xub_StrLen SwxPosition::GetCntIdx() const
4477 return pPam->GetPoint()->nContent.GetIndex();
4480 /* vi:set tabstop=4 shiftwidth=4 expandtab: */