update dev300-m58
[ooovba.git] / sw / source / filter / rtf / swparrtf.cxx
blobf9d6edb24dcbad5c15f076d64563709359de152f
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 <fmthbsh.hxx>
59 #include <fmthdft.hxx>
60 #include <fmtcntnt.hxx>
61 #include <txtftn.hxx>
62 #include <fmtclds.hxx>
63 #include <fmtftn.hxx>
64 #include <fmtfsize.hxx>
65 #include <fmtflcnt.hxx>
66 #include <fmtanchr.hxx>
67 #include <frmatr.hxx>
68 #include <docstat.hxx>
69 #include <swtable.hxx>
70 #include <shellio.hxx>
71 #include <swtypes.hxx>
72 #include <ndtxt.hxx>
73 #include <doc.hxx>
74 #include <docary.hxx>
75 #include <pam.hxx>
76 #include <mdiexp.hxx> // ...Percent()
77 #include <swparrtf.hxx>
78 #include <charfmt.hxx>
79 #include <pagedesc.hxx>
80 #include <ftninfo.hxx>
81 #include <docufld.hxx>
82 #include <flddat.hxx>
83 #include <fltini.hxx>
84 #include <fchrfmt.hxx>
85 #include <paratr.hxx>
86 #ifndef _SECTIOM_HXX
87 #include <section.hxx>
88 #endif
89 #include <fmtclbl.hxx>
90 #include <viewsh.hxx>
91 #include <shellres.hxx>
92 #include <hfspacingitem.hxx>
93 #include <tox.hxx>
94 #include <swerror.h>
95 #ifndef _CMDID_H
96 #include <cmdid.h>
97 #endif
98 #ifndef _STATSTR_HRC
99 #include <statstr.hrc> // ResId fuer Statusleiste
100 #endif
101 #include <SwStyleNameMapper.hxx>
102 #include <tblsel.hxx> // SwSelBoxes
104 #include <docsh.hxx>
105 #include <fmtlsplt.hxx> // SwLayoutSplit
106 #include <svx/keepitem.hxx>
107 #include <svx/svdopath.hxx>
108 #include <svx/svdorect.hxx>
111 #include <fmtsrnd.hxx>
112 #include <fmtfollowtextflow.hxx>
113 #include <svx/svdmodel.hxx>
114 #include <svx/svdpage.hxx>
115 #include <svx/opaqitem.hxx>
116 #include "svx/svdograf.hxx"
117 #include <svx/xflclit.hxx>
118 #include <svx/xlnwtit.hxx>
119 #include <svx/svdoutl.hxx>
120 #include <svx/outlobj.hxx>
121 #include <svx/paperinf.hxx>
123 #include <tools/stream.hxx>
124 #include <basegfx/polygon/b2dpolygon.hxx>
125 #include <basegfx/polygon/b2dpolypolygon.hxx>
126 #include <basegfx/range/b2drange.hxx>
127 #include <vcl/salbtype.hxx> // FRound
129 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
132 using namespace ::com::sun::star;
135 // einige Hilfs-Funktionen
136 // char
137 inline const SvxFontHeightItem& GetSize(const SfxItemSet& rSet,BOOL bInP=TRUE)
138 { return (const SvxFontHeightItem&)rSet.Get( RES_CHRATR_FONTSIZE,bInP); }
139 inline const SvxLRSpaceItem& GetLRSpace(const SfxItemSet& rSet,BOOL bInP=TRUE)
140 { return (const SvxLRSpaceItem&)rSet.Get( RES_LR_SPACE,bInP); }
142 /* \f */
144 extern "C" SAL_DLLPUBLIC_EXPORT Reader* SAL_CALL ImportRTF()
146 return new RtfReader();
149 // Aufruf fuer die allg. Reader-Schnittstelle
150 ULONG RtfReader::Read( SwDoc &rDoc, const String& rBaseURL, SwPaM &rPam, const String &)
152 if( !pStrm )
154 ASSERT( FALSE, "RTF-Read ohne Stream" );
155 return ERR_SWG_READ_ERROR;
158 //JP 18.01.96: Alle Ueberschriften sind normalerweise ohne
159 // Kapitelnummer. Darum hier explizit abschalten
160 // weil das Default jetzt wieder auf AN ist.
161 if( !bInsertMode )
163 Reader::SetNoOutlineNum( rDoc );
165 // MIB 27.09.96: Umrandung uns Abstaende aus Frm-Vorlagen entf.
166 Reader::ResetFrmFmts( rDoc );
169 ULONG nRet = 0;
170 SwDocShell *pDocShell(rDoc.GetDocShell());
171 DBG_ASSERT(pDocShell, "no SwDocShell");
172 uno::Reference<document::XDocumentProperties> xDocProps;
173 if (pDocShell) {
174 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
175 pDocShell->GetModel(), uno::UNO_QUERY_THROW);
176 xDocProps.set(xDPS->getDocumentProperties());
179 SvParserRef xParser = new SwRTFParser( &rDoc, xDocProps,
180 rPam, *pStrm, rBaseURL, !bInsertMode );
181 SvParserState eState = xParser->CallParser();
182 if( SVPAR_PENDING != eState && SVPAR_ACCEPTED != eState )
184 String sErr( String::CreateFromInt32( xParser->GetLineNr() ));
185 sErr += ',';
186 sErr += String::CreateFromInt32( xParser->GetLinePos() );
188 nRet = *new StringErrorInfo( ERR_FORMAT_ROWCOL, sErr,
189 ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
193 return nRet;
196 SwRTFParser::SwRTFParser(SwDoc* pD,
197 uno::Reference<document::XDocumentProperties> i_xDocProps,
198 const SwPaM& rCrsr, SvStream& rIn, const String& rBaseURL,
199 int bReadNewDoc) :
200 SvxRTFParser(pD->GetAttrPool(), rIn, i_xDocProps, bReadNewDoc),
201 maParaStyleMapper(*pD),
202 maCharStyleMapper(*pD),
203 maSegments(*this),
204 maInsertedTables(*pD),
205 aMergeBoxes(0, 5),
206 aTblFmts(0, 10),
207 mpBookmarkStart(0),
208 mpRedlineStack(0),
209 pAuthorInfos(0),
210 pGrfAttrSet(0),
211 pTableNode(0),
212 pOldTblNd(0),
213 pSttNdIdx(0),
214 pRegionEndIdx(0),
215 pDoc(pD),
216 pRelNumRule(new SwRelNumRuleSpaces(*pD, static_cast< BOOL >(bReadNewDoc))),
217 pRedlineInsert(0),
218 pRedlineDelete(0),
219 sBaseURL( rBaseURL ),
220 nAktPageDesc(0),
221 nAktFirstPageDesc(0),
222 nAktBox(0),
223 nInsTblRow(USHRT_MAX),
224 nNewNumSectDef(USHRT_MAX),
225 nRowsToRepeat(0),
226 // --> OD 2008-12-22 #i83368#
227 mbReadCellWhileReadSwFly( false ),
228 // <--
229 bTrowdRead(0),
230 nReadFlyDepth(0),
231 nZOrder(0)
233 mbIsFootnote = mbReadNoTbl = bReadSwFly = bSwPageDesc = bStyleTabValid =
234 bInPgDscTbl = bNewNumList = false;
235 bFirstContinue = true;
236 bContainsPara = false;
237 bContainsTablePara = false;
238 bNestedField = false;
239 bForceNewTable = false;
241 pPam = new SwPaM( *rCrsr.GetPoint() );
242 SetInsPos( SwxPosition( pPam ) );
243 SetChkStyleAttr( 0 != bReadNewDoc );
244 SetCalcValue( FALSE );
245 SetReadDocInfo( TRUE );
247 // diese sollen zusaetzlich ueber \pard zurueck gesetzt werden
248 USHORT temp;
249 temp = RES_TXTATR_CHARFMT; AddPlainAttr( temp );
250 temp = RES_PAGEDESC; AddPardAttr( temp );
251 temp = RES_BREAK; AddPardAttr( temp );
252 temp = RES_PARATR_NUMRULE; AddPardAttr( temp );
253 temp = FN_PARAM_NUM_LEVEL; AddPardAttr( temp );
256 // Aufruf des Parsers
257 SvParserState SwRTFParser::CallParser()
259 mbReadNoTbl = false;
260 bFirstContinue = true;
262 rInput.Seek(STREAM_SEEK_TO_BEGIN);
263 rInput.ResetError();
265 mpRedlineStack = new sw::util::RedlineStack(*pDoc);
267 return SvxRTFParser::CallParser();
270 bool lcl_UsedPara(SwPaM &rPam)
272 const SwCntntNode* pCNd;
273 const SfxItemSet* pSet;
274 if( rPam.GetPoint()->nContent.GetIndex() ||
275 ( 0 != ( pCNd = rPam.GetCntntNode()) &&
276 0 != ( pSet = pCNd->GetpSwAttrSet()) &&
277 ( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, FALSE ) ||
278 SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, FALSE ))))
279 return true;
280 return false;
283 void SwRTFParser::Continue( int nToken )
285 if( bFirstContinue )
287 bFirstContinue = FALSE;
289 if (IsNewDoc())
292 // COMPATIBILITY FLAGS START
294 pDoc->set(IDocumentSettingAccess::PARA_SPACE_MAX, true);
295 pDoc->set(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES, true);
296 pDoc->set(IDocumentSettingAccess::TAB_COMPAT, true);
297 pDoc->set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, true);
298 pDoc->set(IDocumentSettingAccess::USE_HIRES_VIRTUAL_DEVICE, true);
299 pDoc->set(IDocumentSettingAccess::ADD_FLY_OFFSETS, true);
300 pDoc->set(IDocumentSettingAccess::ADD_EXT_LEADING, true);
301 pDoc->set(IDocumentSettingAccess::OLD_NUMBERING, false);
302 pDoc->set(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, false );
303 pDoc->set(IDocumentSettingAccess::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, false);
304 pDoc->set(IDocumentSettingAccess::OLD_LINE_SPACING, false);
305 pDoc->set(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS, true);
306 pDoc->set(IDocumentSettingAccess::USE_FORMER_OBJECT_POS, false);
307 pDoc->set(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING, false);
308 pDoc->set(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION, true);
309 pDoc->set(IDocumentSettingAccess::DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, false); // --> FME 2005-08-11 #i53199#
310 // --> FME 2006-02-10 #131283#
311 pDoc->set(IDocumentSettingAccess::TABLE_ROW_KEEP, true);
312 pDoc->set(IDocumentSettingAccess::IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION, true);
313 pDoc->set(IDocumentSettingAccess::INVERT_BORDER_SPACING, true);
315 // COMPATIBILITY FLAGS END
319 // einen temporaeren Index anlegen, auf Pos 0 so wird er nicht bewegt!
320 pSttNdIdx = new SwNodeIndex( pDoc->GetNodes() );
321 if( !IsNewDoc() ) // in ein Dokument einfuegen ?
323 const SwPosition* pPos = pPam->GetPoint();
324 SwTxtNode* pSttNd = pPos->nNode.GetNode().GetTxtNode();
326 pDoc->SplitNode( *pPos, false );
328 *pSttNdIdx = pPos->nNode.GetIndex()-1;
329 pDoc->SplitNode( *pPos, false );
331 SwPaM aInsertionRangePam( *pPos );
333 pPam->Move( fnMoveBackward );
335 // #106634# split any redline over the insertion point
336 aInsertionRangePam.SetMark();
337 *aInsertionRangePam.GetPoint() = *pPam->GetPoint();
338 aInsertionRangePam.Move( fnMoveBackward );
339 pDoc->SplitRedline( aInsertionRangePam );
341 pDoc->SetTxtFmtColl( *pPam, pDoc->GetTxtCollFromPool
342 ( RES_POOLCOLL_STANDARD, false ));
344 // verhinder das einlesen von Tabellen in Fussnoten / Tabellen
345 ULONG nNd = pPos->nNode.GetIndex();
346 mbReadNoTbl = 0 != pSttNd->FindTableNode() ||
347 ( nNd < pDoc->GetNodes().GetEndOfInserts().GetIndex() &&
348 pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() < nNd );
351 // Laufbalken anzeigen, aber nur bei synchronem Call
352 ULONG nCurrPos = rInput.Tell();
353 rInput.Seek(STREAM_SEEK_TO_END);
354 rInput.ResetError();
355 ::StartProgress( STR_STATSTR_W4WREAD, 0, rInput.Tell(), pDoc->GetDocShell());
356 rInput.Seek( nCurrPos );
357 rInput.ResetError();
360 SvxRTFParser::Continue( nToken );
362 if( SVPAR_PENDING == GetStatus() )
363 return ; // weiter gehts beim naechsten mal
365 pRelNumRule->SetNumRelSpaces( *pDoc );
367 // den Start wieder korrigieren
368 if( !IsNewDoc() && pSttNdIdx->GetIndex() )
370 //die Flys muessen zuerst zurecht gerueckt werden, denn sonst wird
371 // ein am 1. Absatz verankerter Fly falsch eingefuegt
372 if( SVPAR_ACCEPTED == eState )
374 if( aFlyArr.Count() )
375 SetFlysInDoc();
376 pRelNumRule->SetOultineRelSpaces( *pSttNdIdx, pPam->GetPoint()->nNode );
379 SwTxtNode* pTxtNode = pSttNdIdx->GetNode().GetTxtNode();
380 SwNodeIndex aNxtIdx( *pSttNdIdx );
381 if( pTxtNode && pTxtNode->CanJoinNext( &aNxtIdx ))
383 xub_StrLen nStt = pTxtNode->GetTxt().Len();
384 // wenn der Cursor noch in dem Node steht, dann setze in an das Ende
385 if( pPam->GetPoint()->nNode == aNxtIdx )
387 pPam->GetPoint()->nNode = *pSttNdIdx;
388 pPam->GetPoint()->nContent.Assign( pTxtNode, nStt );
391 #ifndef PRODUCT
392 // !!! sollte nicht moeglich sein, oder ??
393 ASSERT( pSttNdIdx->GetIndex()+1 != pPam->GetBound( TRUE ).nNode.GetIndex(),
394 "Pam.Bound1 steht noch im Node" );
395 ASSERT( pSttNdIdx->GetIndex()+1 != pPam->GetBound( FALSE ).nNode.GetIndex(),
396 "Pam.Bound2 steht noch im Node" );
398 if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( TRUE ).nNode.GetIndex() )
400 xub_StrLen nCntPos = pPam->GetBound( TRUE ).nContent.GetIndex();
401 pPam->GetBound( TRUE ).nContent.Assign( pTxtNode,
402 pTxtNode->GetTxt().Len() + nCntPos );
404 if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( FALSE ).nNode.GetIndex() )
406 xub_StrLen nCntPos = pPam->GetBound( FALSE ).nContent.GetIndex();
407 pPam->GetBound( FALSE ).nContent.Assign( pTxtNode,
408 pTxtNode->GetTxt().Len() + nCntPos );
410 #endif
411 // Zeichen Attribute beibehalten!
412 SwTxtNode* pDelNd = aNxtIdx.GetNode().GetTxtNode();
413 if( pTxtNode->GetTxt().Len() )
414 pDelNd->FmtToTxtAttr( pTxtNode );
415 else
416 pTxtNode->ChgFmtColl( pDelNd->GetTxtColl() );
417 pTxtNode->JoinNext();
421 if( SVPAR_ACCEPTED == eState )
423 // den letzen Bereich wieder zumachen
424 if( pRegionEndIdx )
426 // JP 06.01.00: Task 71411 - the last section in WW are not a
427 // balanced Section.
428 if( !GetVersionNo() )
430 SwSectionNode* pSectNd = pRegionEndIdx->GetNode().
431 StartOfSectionNode()->GetSectionNode();
432 if( pSectNd )
433 pSectNd->GetSection().GetFmt()->SetFmtAttr(
434 SwFmtNoBalancedColumns( TRUE ) );
437 DelLastNode();
438 pPam->GetPoint()->nNode = *pRegionEndIdx;
439 pPam->Move( fnMoveForward, fnGoNode );
440 delete pRegionEndIdx, pRegionEndIdx = 0;
443 sal_uInt16 nPageDescOffset = pDoc->GetPageDescCnt();
444 maSegments.InsertSegments(IsNewDoc());
445 UpdatePageDescs(*pDoc, nPageDescOffset);
446 //$flr folloing garbe collecting code has been moved from the previous procedure
447 // UpdatePageDescs to here in order to fix bug #117882#
448 rtfSections::myrDummyIter aDEnd = maSegments.maDummyPageNos.rend();
449 for (rtfSections::myrDummyIter aI = maSegments.maDummyPageNos.rbegin(); aI != aDEnd; ++aI)
450 pDoc->DelPageDesc(*aI);
453 if( aFlyArr.Count() )
454 SetFlysInDoc();
456 // jetzt noch den letzten ueberfluessigen Absatz loeschen
457 SwPosition* pPos = pPam->GetPoint();
458 if( !pPos->nContent.GetIndex() )
460 SwTxtNode* pAktNd;
461 ULONG nNodeIdx = pPos->nNode.GetIndex();
462 if( IsNewDoc() )
464 SwNode* pTmp = pDoc->GetNodes()[ nNodeIdx -1 ];
465 if( pTmp->IsCntntNode() && !pTmp->FindTableNode() )
467 // --> FME 2006-02-15 #131200# Do not delete the paragraph
468 // if it has anchored objects:
469 bool bAnchoredObjs = false;
470 const SwSpzFrmFmts* pFrmFmts = pDoc->GetSpzFrmFmts();
471 if ( pFrmFmts && pFrmFmts->Count() )
473 for ( USHORT nI = pFrmFmts->Count(); nI; --nI )
475 const SwFmtAnchor & rAnchor = (*pFrmFmts)[ nI - 1 ]->GetAnchor();
476 if ( FLY_AT_CNTNT == rAnchor.GetAnchorId() ||
477 FLY_AUTO_CNTNT == rAnchor.GetAnchorId() )
479 const SwPosition * pObjPos = rAnchor.GetCntntAnchor();
480 if ( pObjPos && nNodeIdx == pObjPos->nNode.GetIndex() )
482 bAnchoredObjs = true;
483 break;
488 // <--
490 if ( !bAnchoredObjs )
491 DelLastNode();
494 else if (0 != (pAktNd = pDoc->GetNodes()[nNodeIdx]->GetTxtNode()))
496 if( pAktNd->CanJoinNext( &pPos->nNode ))
498 SwTxtNode* pNextNd = pPos->nNode.GetNode().GetTxtNode();
499 pPos->nContent.Assign( pNextNd, 0 );
500 pPam->SetMark(); pPam->DeleteMark();
501 pNextNd->JoinPrev();
503 else if( !pAktNd->GetTxt().Len() &&
504 pAktNd->StartOfSectionIndex()+2 <
505 pAktNd->EndOfSectionIndex() )
507 pPos->nContent.Assign( 0, 0 );
508 pPam->SetMark(); pPam->DeleteMark();
509 pDoc->GetNodes().Delete( pPos->nNode, 1 );
510 pPam->Move( fnMoveBackward );
514 // nun noch das SplitNode vom Ende aufheben
515 else if( !IsNewDoc() )
517 if( pPos->nContent.GetIndex() ) // dann gabs am Ende kein \par,
518 pPam->Move( fnMoveForward, fnGoNode ); // als zum naechsten Node
519 SwTxtNode* pTxtNode = pPos->nNode.GetNode().GetTxtNode();
520 SwNodeIndex aPrvIdx( pPos->nNode );
521 if( pTxtNode && pTxtNode->CanJoinPrev( &aPrvIdx ) &&
522 *pSttNdIdx <= aPrvIdx )
524 // eigentlich muss hier ein JoinNext erfolgen, aber alle Cursor
525 // usw. sind im pTxtNode angemeldet, so dass der bestehen
526 // bleiben MUSS.
528 // Absatz in Zeichen-Attribute umwandeln, aus dem Prev die
529 // Absatzattribute und die Vorlage uebernehmen!
530 SwTxtNode* pPrev = aPrvIdx.GetNode().GetTxtNode();
531 pTxtNode->ChgFmtColl( pPrev->GetTxtColl() );
532 pTxtNode->FmtToTxtAttr( pPrev );
533 pTxtNode->ResetAllAttr();
535 if( pPrev->HasSwAttrSet() )
536 pTxtNode->SetAttr( *pPrev->GetpSwAttrSet() );
538 if( &pPam->GetBound(TRUE).nNode.GetNode() == pPrev )
539 pPam->GetBound(TRUE).nContent.Assign( pTxtNode, 0 );
540 if( &pPam->GetBound(FALSE).nNode.GetNode() == pPrev )
541 pPam->GetBound(FALSE).nContent.Assign( pTxtNode, 0 );
543 pTxtNode->JoinPrev();
547 delete pSttNdIdx, pSttNdIdx = 0;
548 delete pRegionEndIdx, pRegionEndIdx = 0;
549 RemoveUnusedNumRules();
551 pDoc->SetUpdateExpFldStat(true);
552 pDoc->SetInitDBFields(true);
554 // Laufbalken bei asynchronen Call nicht einschalten !!!
555 ::EndProgress( pDoc->GetDocShell() );
558 bool rtfSections::SetCols(SwFrmFmt &rFmt, const rtfSection &rSection,
559 USHORT nNettoWidth)
561 //sprmSCcolumns - Anzahl der Spalten - 1
562 USHORT nCols = static_cast< USHORT >(rSection.NoCols());
564 if (nCols < 2)
565 return false; // keine oder bloedsinnige Spalten
567 SwFmtCol aCol; // Erzeuge SwFmtCol
569 //sprmSDxaColumns - Default-Abstand 1.25 cm
570 USHORT nColSpace = static_cast< USHORT >(rSection.StandardColSeperation());
572 aCol.Init( nCols, nColSpace, nNettoWidth );
574 // not SFEvenlySpaced
575 if (rSection.maPageInfo.maColumns.size())
577 aCol._SetOrtho(false);
578 USHORT nWishWidth = 0, nHalfPrev = 0;
579 for(USHORT n=0, i=0; n < rSection.maPageInfo.maColumns.size() && i < nCols; n += 2, ++i )
581 SwColumn* pCol = aCol.GetColumns()[ i ];
582 pCol->SetLeft( nHalfPrev );
583 USHORT nSp = static_cast< USHORT >(rSection.maPageInfo.maColumns[ n+1 ]);
584 nHalfPrev = nSp / 2;
585 pCol->SetRight( nSp - nHalfPrev );
586 pCol->SetWishWidth( static_cast< USHORT >(rSection.maPageInfo.maColumns[ n ]) +
587 pCol->GetLeft() + pCol->GetRight());
588 nWishWidth = nWishWidth + pCol->GetWishWidth();
590 aCol.SetWishWidth( nWishWidth );
593 rFmt.SetFmtAttr(aCol);
594 return true;
597 void rtfSections::SetPage(SwPageDesc &rInPageDesc, SwFrmFmt &rFmt,
598 const rtfSection &rSection, bool bIgnoreCols)
600 // 1. Orientierung
601 rInPageDesc.SetLandscape(rSection.IsLandScape());
603 // 2. Papiergroesse
604 SwFmtFrmSize aSz(rFmt.GetFrmSize());
605 aSz.SetWidth(rSection.GetPageWidth());
606 aSz.SetHeight(rSection.GetPageHeight());
607 rFmt.SetFmtAttr(aSz);
609 rFmt.SetFmtAttr(
610 SvxLRSpaceItem(rSection.GetPageLeft(), rSection.GetPageRight(), 0, 0, RES_LR_SPACE));
612 if (!bIgnoreCols)
614 SetCols(rFmt, rSection, static_cast< USHORT >(rSection.GetPageWidth() -
615 rSection.GetPageLeft() - rSection.GetPageRight()));
618 rFmt.SetFmtAttr(rSection.maPageInfo.maBox);
621 bool HasHeader(const SwFrmFmt &rFmt)
623 const SfxPoolItem *pHd;
624 if (SFX_ITEM_SET == rFmt.GetItemState(RES_HEADER, false, &pHd))
625 return ((const SwFmtHeader *)(pHd))->IsActive();
626 return false;
629 bool HasFooter(const SwFrmFmt &rFmt)
631 const SfxPoolItem *pFt;
632 if (SFX_ITEM_SET == rFmt.GetItemState(RES_FOOTER, false, &pFt))
633 return ((const SwFmtFooter *)(pFt))->IsActive();
634 return false;
637 void rtfSections::GetPageULData(const rtfSection &rSection, bool bFirst,
638 rtfSections::wwULSpaceData& rData)
640 short nWWUp = static_cast< short >(rSection.maPageInfo.mnMargtsxn);
641 short nWWLo = static_cast< short >(rSection.maPageInfo.mnMargbsxn);
642 short nWWHTop = static_cast< short >(rSection.maPageInfo.mnHeadery);
643 short nWWFBot = static_cast< short >(rSection.maPageInfo.mnFootery);
645 if (bFirst)
647 if (
648 rSection.mpTitlePage && HasHeader(rSection.mpTitlePage->GetMaster())
651 rData.bHasHeader = true;
654 else
656 if (rSection.mpPage &&
658 HasHeader(rSection.mpPage->GetMaster())
659 || HasHeader(rSection.mpPage->GetLeft())
663 rData.bHasHeader = true;
667 if( rData.bHasHeader )
669 rData.nSwUp = nWWHTop; // Header -> umrechnen, see ww8par6.cxx
671 if ( nWWUp > 0 && nWWUp >= nWWHTop )
672 rData.nSwHLo = nWWUp - nWWHTop;
673 else
674 rData.nSwHLo = 0;
676 if (rData.nSwHLo < cMinHdFtHeight)
677 rData.nSwHLo = cMinHdFtHeight;
679 else // kein Header -> Up einfach uebernehmen
680 rData.nSwUp = Abs(nWWUp);
682 if (bFirst)
684 if (
685 rSection.mpTitlePage &&
686 HasFooter(rSection.mpTitlePage->GetMaster())
689 rData.bHasFooter = true;
692 else
694 if (rSection.mpPage &&
696 HasFooter(rSection.mpPage->GetMaster())
697 || HasFooter(rSection.mpPage->GetLeft())
701 rData.bHasFooter = true;
705 if( rData.bHasFooter )
707 rData.nSwLo = nWWFBot; // Footer -> Umrechnen
708 if ( nWWLo > 0 && nWWLo >= nWWFBot )
709 rData.nSwFUp = nWWLo - nWWFBot;
710 else
711 rData.nSwFUp = 0;
713 if (rData.nSwFUp < cMinHdFtHeight)
714 rData.nSwFUp = cMinHdFtHeight;
716 else // kein Footer -> Lo einfach uebernehmen
717 rData.nSwLo = Abs(nWWLo);
720 void rtfSections::SetPageULSpaceItems(SwFrmFmt &rFmt,
721 rtfSections::wwULSpaceData& rData)
723 if (rData.bHasHeader) // ... und Header-Lower setzen
725 //Kopfzeilenhoehe minimal sezten
726 if (SwFrmFmt* pHdFmt = (SwFrmFmt*)rFmt.GetHeader().GetHeaderFmt())
728 pHdFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwHLo));
729 SvxULSpaceItem aHdUL(pHdFmt->GetULSpace());
730 aHdUL.SetLower( rData.nSwHLo - cMinHdFtHeight );
731 pHdFmt->SetFmtAttr(aHdUL);
732 pHdFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
733 RES_HEADER_FOOTER_EAT_SPACING, true));
737 if (rData.bHasFooter) // ... und Footer-Upper setzen
739 if (SwFrmFmt* pFtFmt = (SwFrmFmt*)rFmt.GetFooter().GetFooterFmt())
741 pFtFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwFUp));
742 SvxULSpaceItem aFtUL(pFtFmt->GetULSpace());
743 aFtUL.SetUpper( rData.nSwFUp - cMinHdFtHeight );
744 pFtFmt->SetFmtAttr(aFtUL);
745 pFtFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
746 RES_HEADER_FOOTER_EAT_SPACING, true));
750 SvxULSpaceItem aUL(rData.nSwUp, rData.nSwLo, RES_UL_SPACE ); // Page-UL setzen
751 rFmt.SetFmtAttr(aUL);
754 void rtfSections::SetSegmentToPageDesc(const rtfSection &rSection,
755 bool bTitlePage, bool bIgnoreCols)
757 SwPageDesc &rPage = bTitlePage ? *rSection.mpTitlePage : *rSection.mpPage;
759 // SetNumberingType(rSection, rPage);
761 SwFrmFmt &rFmt = rPage.GetMaster();
762 // mrReader.SetDocumentGrid(rFmt, rSection);
764 wwULSpaceData aULData;
765 GetPageULData(rSection, bTitlePage, aULData);
766 SetPageULSpaceItems(rFmt, aULData);
768 SetPage(rPage, rFmt, rSection, bIgnoreCols);
770 UseOnPage ePage = rPage.ReadUseOn();
771 if(ePage & nsUseOnPage::PD_ALL)
773 SwFrmFmt &rFmtLeft = rPage.GetLeft();
774 SetPageULSpaceItems(rFmtLeft, aULData);
775 SetPage(rPage, rFmtLeft, rSection, bIgnoreCols);
780 void rtfSections::CopyFrom(const SwPageDesc &rFrom, SwPageDesc &rDest)
782 UseOnPage ePage = rFrom.ReadUseOn();
783 rDest.WriteUseOn(ePage);
785 mrReader.pDoc->CopyHeader(rFrom.GetMaster(), rDest.GetMaster());
786 SwFrmFmt &rDestFmt = rDest.GetMaster();
787 rDestFmt.SetFmtAttr(rFrom.GetMaster().GetHeader());
788 mrReader.pDoc->CopyHeader(rFrom.GetLeft(), rDest.GetLeft());
789 mrReader.pDoc->CopyFooter(rFrom.GetMaster(), rDest.GetMaster());
790 mrReader.pDoc->CopyFooter(rFrom.GetLeft(), rDest.GetLeft());
793 void rtfSections::MoveFrom(SwPageDesc &rFrom, SwPageDesc &rDest)
795 UseOnPage ePage = rFrom.ReadUseOn();
796 rDest.WriteUseOn(ePage);
798 SwFrmFmt &rDestMaster = rDest.GetMaster();
799 SwFrmFmt &rFromMaster = rFrom.GetMaster();
800 rDestMaster.SetFmtAttr(rFromMaster.GetHeader());
801 rDestMaster.SetFmtAttr(rFromMaster.GetFooter());
802 //rFromMaster.SetAttr(SwFmtHeader()); //$flr uncommented due to bug fix #117882#
803 //rFromMaster.SetAttr(SwFmtFooter()); //$flr uncommented due to bug fix #117882#
805 SwFrmFmt &rDestLeft = rDest.GetLeft();
806 SwFrmFmt &rFromLeft = rFrom.GetLeft();
807 rDestLeft.SetFmtAttr(rFromLeft.GetHeader());
808 rDestLeft.SetFmtAttr(rFromLeft.GetFooter());
809 //rFromLeft.SetAttr(SwFmtHeader()); //$flr uncommented due to bug fix #117882#
810 //rFromLeft.SetAttr(SwFmtFooter()); //$flr uncommented due to bug fix #117882#
813 void rtfSections::SetHdFt(rtfSection &rSection)
815 ASSERT(rSection.mpPage, "makes no sense to call without a main page");
816 if (rSection.mpPage && rSection.maPageInfo.mpPageHdFt)
818 if (rSection.maPageInfo.mbPageHdFtUsed)
820 MoveFrom(*rSection.maPageInfo.mpPageHdFt, *rSection.mpPage);
821 rSection.maPageInfo.mbPageHdFtUsed = false;
822 rSection.maPageInfo.mpPageHdFt = rSection.mpPage;
824 else
825 CopyFrom(*rSection.maPageInfo.mpPageHdFt, *rSection.mpPage);
828 if (rSection.mpTitlePage && rSection.maPageInfo.mpTitlePageHdFt)
830 if (rSection.maPageInfo.mbTitlePageHdFtUsed)
832 MoveFrom(*rSection.maPageInfo.mpTitlePageHdFt,
833 *rSection.mpTitlePage);
834 rSection.maPageInfo.mbTitlePageHdFtUsed = false;
835 rSection.maPageInfo.mpTitlePageHdFt = rSection.mpTitlePage;
837 else
839 CopyFrom(*rSection.maPageInfo.mpTitlePageHdFt,
840 *rSection.mpTitlePage);
845 SwSectionFmt *rtfSections::InsertSection(SwPaM& rMyPaM, rtfSection &rSection)
847 SwSection aSection(CONTENT_SECTION, mrReader.pDoc->GetUniqueSectionName());
849 SfxItemSet aSet( mrReader.pDoc->GetAttrPool(), aFrmFmtSetRange );
851 sal_uInt8 nRTLPgn = maSegments.empty() ? 0 : maSegments.back().IsBiDi();
852 aSet.Put(SvxFrameDirectionItem(
853 nRTLPgn ? FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR));
855 rSection.mpSection = mrReader.pDoc->Insert( rMyPaM, aSection, &aSet );
856 ASSERT(rSection.mpSection, "section not inserted!");
857 if (!rSection.mpSection)
858 return 0;
860 SwPageDesc *pPage = 0;
861 mySegrIter aEnd = maSegments.rend();
862 for (mySegrIter aIter = maSegments.rbegin(); aIter != aEnd; ++aIter)
864 pPage = aIter->mpPage;
865 if (pPage)
866 break;
869 ASSERT(pPage, "no page outside this section!");
871 if (!pPage)
872 pPage = &mrReader.pDoc->_GetPageDesc(0);
874 if (!pPage)
875 return 0;
877 SwFrmFmt& rFmt = pPage->GetMaster();
878 const SwFmtFrmSize& rSz = rFmt.GetFrmSize();
879 const SvxLRSpaceItem& rLR = rFmt.GetLRSpace();
880 SwTwips nWidth = rSz.GetWidth();
881 long nLeft = rLR.GetTxtLeft();
882 long nRight = rLR.GetRight();
884 SwSectionFmt *pFmt = rSection.mpSection->GetFmt();
885 ASSERT(pFmt, "impossible");
886 if (!pFmt)
887 return 0;
888 SetCols(*pFmt, rSection, (USHORT)(nWidth - nLeft - nRight) );
890 return pFmt;
893 void rtfSections::InsertSegments(bool bNewDoc)
895 sal_uInt16 nDesc(0);
896 mySegIter aEnd = maSegments.end();
897 mySegIter aStart = maSegments.begin();
898 for (mySegIter aIter = aStart; aIter != aEnd; ++aIter)
900 mySegIter aNext = aIter+1;
902 bool bInsertSection = aIter != aStart ? aIter->IsContinous() : false;
904 if (!bInsertSection)
907 If a cont section follow this section then we won't be
908 creating a page desc with 2+ cols as we cannot host a one
909 col section in a 2+ col pagedesc and make it look like
910 word. But if the current section actually has columns then
911 we are forced to insert a section here as well as a page
912 descriptor.
916 Note for the future:
917 If we want to import "protected sections" the here is
918 where we would also test for that and force a section
919 insertion if that was true.
921 bool bIgnoreCols = false;
922 if (aNext != aEnd && aNext->IsContinous())
924 bIgnoreCols = true;
925 if (aIter->NoCols() > 1)
926 bInsertSection = true;
929 if (aIter->HasTitlePage())
931 if (bNewDoc && aIter == aStart)
933 aIter->mpTitlePage =
934 mrReader.pDoc->GetPageDescFromPool(RES_POOLPAGE_FIRST);
936 else
938 USHORT nPos = mrReader.pDoc->MakePageDesc(
939 ViewShell::GetShellRes()->GetPageDescName(nDesc)
940 , 0, false);
941 aIter->mpTitlePage = &mrReader.pDoc->_GetPageDesc(nPos);
943 ASSERT(aIter->mpTitlePage, "no page!");
944 if (!aIter->mpTitlePage)
945 continue;
947 SetSegmentToPageDesc(*aIter, true, bIgnoreCols);
950 if (!bNewDoc && aIter == aStart)
951 continue;
952 else if (bNewDoc && aIter == aStart)
954 aIter->mpPage =
955 mrReader.pDoc->GetPageDescFromPool(RES_POOLPAGE_STANDARD);
957 else
959 USHORT nPos = mrReader.pDoc->MakePageDesc(
960 ViewShell::GetShellRes()->GetPageDescName(nDesc,
961 false, aIter->HasTitlePage()),
962 aIter->mpTitlePage, false);
963 aIter->mpPage = &mrReader.pDoc->_GetPageDesc(nPos);
965 ASSERT(aIter->mpPage, "no page!");
966 if (!aIter->mpPage)
967 continue;
969 SetHdFt(*aIter);
971 if (aIter->mpTitlePage)
972 SetSegmentToPageDesc(*aIter, true, bIgnoreCols);
973 SetSegmentToPageDesc(*aIter, false, bIgnoreCols);
975 SwFmtPageDesc aPgDesc(aIter->HasTitlePage() ?
976 aIter->mpTitlePage : aIter->mpPage);
978 if (aIter->mpTitlePage)
979 aIter->mpTitlePage->SetFollow(aIter->mpPage);
981 if (aIter->PageRestartNo() ||
982 ((aIter == aStart) && aIter->PageStartAt() != 1))
983 aPgDesc.SetNumOffset( static_cast< USHORT >(aIter->PageStartAt()) );
986 If its a table here, apply the pagebreak to the table
987 properties, otherwise we add it to the para at this
988 position
990 if (aIter->maStart.GetNode().IsTableNode())
992 SwTable& rTable =
993 aIter->maStart.GetNode().GetTableNode()->GetTable();
994 SwFrmFmt* pApply = rTable.GetFrmFmt();
995 ASSERT(pApply, "impossible");
996 if (pApply)
997 pApply->SetFmtAttr(aPgDesc);
999 else
1001 SwPosition aPamStart(aIter->maStart);
1002 aPamStart.nContent.Assign(
1003 aIter->maStart.GetNode().GetCntntNode(), 0);
1004 SwPaM aPage(aPamStart);
1006 mrReader.pDoc->Insert(aPage, aPgDesc, 0);
1008 ++nDesc;
1011 SwTxtNode* pTxtNd = 0;
1012 if (bInsertSection)
1014 SwPaM aSectPaM(*mrReader.pPam);
1015 SwNodeIndex aAnchor(aSectPaM.GetPoint()->nNode);
1016 if (aNext != aEnd)
1018 aAnchor = aNext->maStart;
1019 aSectPaM.GetPoint()->nNode = aAnchor;
1020 aSectPaM.GetPoint()->nContent.Assign(
1021 aNext->maStart.GetNode().GetCntntNode(), 0);
1022 aSectPaM.Move(fnMoveBackward);
1025 const SwPosition* pPos = aSectPaM.GetPoint();
1026 const SwTxtNode* pSttNd =
1027 mrReader.pDoc->GetNodes()[ pPos->nNode ]->GetTxtNode();
1028 const SwTableNode* pTableNd = pSttNd ? pSttNd->FindTableNode() : 0;
1029 if (pTableNd)
1031 pTxtNd =
1032 mrReader.pDoc->GetNodes().MakeTxtNode(aAnchor,
1033 mrReader.pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT ));
1035 aSectPaM.GetPoint()->nNode = SwNodeIndex(*pTxtNd);
1036 aSectPaM.GetPoint()->nContent.Assign(
1037 aSectPaM.GetCntntNode(), 0);
1040 aSectPaM.SetMark();
1042 aSectPaM.GetPoint()->nNode = aIter->maStart;
1043 aSectPaM.GetPoint()->nContent.Assign(
1044 aSectPaM.GetCntntNode(), 0);
1046 SwSectionFmt *pRet = InsertSection(aSectPaM, *aIter);
1047 //The last section if continous is always unbalanced
1048 if (aNext == aEnd && pRet)
1049 pRet->SetFmtAttr(SwFmtNoBalancedColumns(true));
1052 if (pTxtNd)
1054 SwNodeIndex aIdx(*pTxtNd);
1055 SwPosition aPos(aIdx);
1056 SwPaM aTest(aPos);
1057 mrReader.pDoc->DelFullPara(aTest);
1058 pTxtNd = 0;
1063 namespace sw{
1064 namespace util{
1066 InsertedTableClient::InsertedTableClient(SwTableNode & rNode)
1068 rNode.Add(this);
1071 SwTableNode * InsertedTableClient::GetTableNode()
1073 return dynamic_cast<SwTableNode *> (pRegisteredIn);
1076 InsertedTablesManager::InsertedTablesManager(const SwDoc &rDoc)
1077 : mbHasRoot(rDoc.GetRootFrm())
1081 void InsertedTablesManager::DelAndMakeTblFrms()
1083 if (!mbHasRoot)
1084 return;
1085 TblMapIter aEnd = maTables.end();
1086 for (TblMapIter aIter = maTables.begin(); aIter != aEnd; ++aIter)
1088 // exitiert schon ein Layout, dann muss an dieser Tabelle die BoxFrames
1089 // neu erzeugt
1090 SwTableNode *pTable = aIter->first->GetTableNode();
1091 ASSERT(pTable, "Why no expected table");
1092 if (pTable)
1094 SwFrmFmt * pFrmFmt = pTable->GetTable().GetFrmFmt();
1096 if (pFrmFmt != NULL)
1098 SwNodeIndex *pIndex = aIter->second;
1099 pTable->DelFrms();
1100 pTable->MakeFrms(pIndex);
1106 void InsertedTablesManager::InsertTable(SwTableNode &rTableNode, SwPaM &rPaM)
1108 if (!mbHasRoot)
1109 return;
1110 //Associate this tablenode with this after position, replace an //old
1111 //node association if necessary
1113 InsertedTableClient * pClient = new InsertedTableClient(rTableNode);
1115 maTables.insert(TblMap::value_type(pClient, &(rPaM.GetPoint()->nNode)));
1120 SwRTFParser::~SwRTFParser()
1122 maInsertedTables.DelAndMakeTblFrms();
1123 mpRedlineStack->closeall(*pPam->GetPoint());
1124 delete mpRedlineStack;
1126 delete pSttNdIdx;
1127 delete pRegionEndIdx;
1128 delete pPam;
1129 delete pRelNumRule;
1131 if (aFlyArr.Count())
1132 aFlyArr.DeleteAndDestroy( 0, aFlyArr.Count() );
1134 if (pGrfAttrSet)
1135 DELETEZ( pGrfAttrSet );
1137 DELETEZ( pAuthorInfos );
1140 //i19718
1141 void SwRTFParser::ReadShpRslt()
1143 int nToken;
1144 while ('}' != (nToken = GetNextToken() ) && IsParserWorking())
1146 switch(nToken)
1148 case RTF_PAR:
1149 break;
1150 default:
1151 NextToken(nToken);
1152 break;
1155 SkipToken(-1);
1158 void SwRTFParser::ReadShpTxt(String& s)
1160 int nToken;
1161 int level=1;
1162 s.AppendAscii("{\\rtf");
1163 while (level>0 && IsParserWorking())
1165 nToken = GetNextToken();
1166 switch(nToken)
1168 case RTF_SN:
1169 case RTF_SV:
1170 SkipGroup();
1171 break;
1172 case RTF_TEXTTOKEN:
1173 s.Append(aToken);
1174 break;
1175 case '{':
1176 level++;
1177 s.Append(String::CreateFromAscii("{"));
1178 break;
1179 case '}':
1180 level--;
1181 s.Append(String::CreateFromAscii("}"));
1182 break;
1183 default:
1184 s.Append(aToken);
1185 if (bTokenHasValue) {
1186 s.Append(String::CreateFromInt64(nTokenValue));
1188 s.Append(String::CreateFromAscii(" "));
1189 break;
1192 SkipToken(-1);
1196 * #127429#. Very basic support for the "Buchhalternase".
1198 void SwRTFParser::ReadDrawingObject()
1200 int nToken;
1201 int level;
1202 level=1;
1203 Rectangle aRect;
1204 ::basegfx::B2DPolygon aPolygon;
1205 ::basegfx::B2DPoint aPoint;
1206 bool bPolygonActive(false);
1208 while (level>0 && IsParserWorking())
1210 nToken = GetNextToken();
1211 switch(nToken)
1213 case '}':
1214 level--;
1215 break;
1216 case '{':
1217 level++;
1218 break;
1219 case RTF_DPX:
1220 aRect.setX(nTokenValue);
1221 break;
1222 case RTF_DPXSIZE:
1223 aRect.setWidth(nTokenValue);
1224 break;
1225 case RTF_DPY:
1226 aRect.setY(nTokenValue);
1227 break;
1228 case RTF_DPYSIZE:
1229 aRect.setHeight(nTokenValue);
1230 break;
1231 case RTF_DPPOLYCOUNT:
1232 bPolygonActive = true;
1233 break;
1234 case RTF_DPPTX:
1235 aPoint.setX(nTokenValue);
1236 break;
1237 case RTF_DPPTY:
1238 aPoint.setY(nTokenValue);
1240 if(bPolygonActive)
1242 aPolygon.append(aPoint);
1245 break;
1246 default:
1247 break;
1250 SkipToken(-1);
1252 const Point aPointC1( 0, 0 );
1253 const Point aPointC2( 100, 200 );
1254 const Point aPointC3( 300, 400 );
1255 XPolygon aPolygonC(3);
1256 aPolygonC[0] = aPointC1;
1257 aPolygonC[1] = aPointC2;
1258 aPolygonC[2] = aPointC3;
1260 if(bPolygonActive && aPolygon.count())
1262 SdrPathObj* pStroke = new SdrPathObj(OBJ_PLIN, ::basegfx::B2DPolyPolygon(aPolygon));
1263 SfxItemSet aFlySet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1);
1264 SwFmtSurround aSur( SURROUND_PARALLEL );
1265 aSur.SetContour( false );
1266 aSur.SetOutside(true);
1267 aFlySet.Put( aSur );
1268 SwFmtFollowTextFlow aFollowTextFlow( FALSE );
1269 aFlySet.Put( aFollowTextFlow );
1271 sw::util::SetLayer aSetLayer(*pDoc);
1272 aSetLayer.SendObjectToHeaven(*pStroke);
1275 FLY_AT_CNTNT, //Absatzgebundener Rahmen <to paragraph>
1276 FLY_IN_CNTNT, //Zeichengebundener Rahmen <as character>
1277 FLY_PAGE, //Seitengebundener Rahmen <to page>
1278 FLY_AT_FLY, //Rahmengebundener Rahmen ( LAYER_IMPL ) <to frame>
1279 FLY_AUTO_CNTNT, //Automatisch positionierter, absatzgebundener Rahmen <to character>
1281 SwFmtAnchor aAnchor( FLY_AT_CNTNT );
1282 aAnchor.SetAnchor( pPam->GetPoint() );
1283 aFlySet.Put( aAnchor );
1286 text::RelOrientation::FRAME, // Absatz inkl. Raender
1287 text::RelOrientation::PRINT_AREA, // Absatz ohne Raender
1288 text::RelOrientation::CHAR, // an einem Zeichen
1289 text::RelOrientation::PAGE_LEFT, // im linken Seitenrand
1290 text::RelOrientation::PAGE_RIGHT, // im rechten Seitenrand
1291 text::RelOrientation::FRAME_LEFT, // im linken Absatzrand
1292 text::RelOrientation::FRAME_RIGHT, // im rechten Absatzrand
1293 text::RelOrientation::PAGE_FRAME, // Seite inkl. Raender, bei seitengeb. identisch mit text::RelOrientation::FRAME
1294 text::RelOrientation::PAGE_PRINT_AREA, // Seite ohne Raender, bei seitengeb. identisch mit text::RelOrientation::PRTAREA
1295 // OD 11.11.2003 #i22341#
1296 text::RelOrientation::TEXT_LINE, // vertical relative to top of text line, only for to-character
1297 // anchored objects.
1300 text::HoriOrientation::NONE, //Der Wert in nYPos gibt die RelPos direkt an.
1301 text::HoriOrientation::RIGHT, //Der Rest ist fuer automatische Ausrichtung.
1302 text::HoriOrientation::CENTER,
1303 text::HoriOrientation::LEFT,
1304 text::HoriOrientation::INSIDE,
1305 text::HoriOrientation::OUTSIDE,
1306 text::HoriOrientation::FULL, //Spezialwert fuer Tabellen
1307 text::HoriOrientation::LEFT_AND_WIDTH //Auch fuer Tabellen
1309 SwFmtHoriOrient aHori( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME );
1310 aFlySet.Put( aHori );
1312 text::VertOrientation::NONE, //Der Wert in nYPos gibt die RelPos direkt an.
1313 text::VertOrientation::TOP, //Der Rest ist fuer automatische Ausrichtung.
1314 text::VertOrientation::CENTER,
1315 text::VertOrientation::BOTTOM,
1316 text::VertOrientation::CHAR_TOP, //Ausrichtung _nur_ fuer Zeichengebundene Rahmen
1317 text::VertOrientation::CHAR_CENTER, //wie der Name jew. sagt wird der RefPoint des Rahmens
1318 text::VertOrientation::CHAR_BOTTOM, //entsprechend auf die Oberkante, Mitte oder Unterkante
1319 text::VertOrientation::LINE_TOP, //der Zeile gesetzt. Der Rahmen richtet sich dann
1320 text::VertOrientation::LINE_CENTER, //entsprechend aus.
1321 text::VertOrientation::LINE_BOTTOM
1323 SwFmtVertOrient aVert( 0, text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME );
1324 aFlySet.Put( aVert );
1326 pDoc->GetOrCreateDrawModel();
1327 SdrModel* pDrawModel = pDoc->GetDrawModel();
1328 SdrPage* pDrawPg = pDrawModel->GetPage(0);
1329 pDrawPg->InsertObject(pStroke, 0);
1331 pStroke->SetSnapRect(aRect);
1333 /* SwFrmFmt* pRetFrmFmt = */pDoc->Insert(*pPam, *pStroke, &aFlySet, NULL);
1337 void SwRTFParser::InsertShpObject(SdrObject* pStroke, int _nZOrder)
1339 SfxItemSet aFlySet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1);
1340 SwFmtSurround aSur( SURROUND_THROUGHT );
1341 aSur.SetContour( false );
1342 aSur.SetOutside(true);
1343 aFlySet.Put( aSur );
1344 SwFmtFollowTextFlow aFollowTextFlow( FALSE );
1345 aFlySet.Put( aFollowTextFlow );
1347 SwFmtAnchor aAnchor( FLY_AT_CNTNT );
1348 aAnchor.SetAnchor( pPam->GetPoint() );
1349 aFlySet.Put( aAnchor );
1352 SwFmtHoriOrient aHori( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME );
1353 aFlySet.Put( aHori );
1355 SwFmtVertOrient aVert( 0, text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME );
1356 aFlySet.Put( aVert );
1358 aFlySet.Put(SvxOpaqueItem(RES_OPAQUE,false));
1360 pDoc->GetOrCreateDrawModel();
1361 SdrModel* pDrawModel = pDoc->GetDrawModel();
1362 SdrPage* pDrawPg = pDrawModel->GetPage(0);
1363 pDrawPg->InsertObject(pStroke);
1364 pDrawPg->SetObjectOrdNum(pStroke->GetOrdNum(), _nZOrder);
1365 /* SwFrmFmt* pRetFrmFmt = */pDoc->Insert(*pPam, *pStroke, &aFlySet, NULL);
1368 ::basegfx::B2DPoint rotate(const ::basegfx::B2DPoint& rStart, const ::basegfx::B2DPoint& rEnd)
1370 const ::basegfx::B2DVector aVector(rStart - rEnd);
1371 return ::basegfx::B2DPoint(aVector.getY() + rEnd.getX(), -aVector.getX() + rEnd.getY());
1375 void SwRTFParser::ReadShapeObject()
1377 int nToken;
1378 int level;
1379 level=1;
1380 ::basegfx::B2DPoint aPointLeftTop;
1381 ::basegfx::B2DPoint aPointRightBottom;
1382 String sn;
1383 sal_Int32 shapeType=-1;
1384 Graphic aGrf;
1385 bool bGrfValid=false;
1386 bool fFilled=true;
1387 Color fillColor(255, 255, 255);
1388 bool fLine=true;
1389 int lineWidth=9525/360;
1390 String shpTxt;
1391 bool bshpTxt=false;
1392 int txflTextFlow=0;
1395 while (level>0 && IsParserWorking())
1397 nToken = GetNextToken();
1398 switch(nToken)
1400 case '}':
1401 level--;
1402 break;
1403 case '{':
1404 level++;
1405 break;
1406 case RTF_SHPLEFT:
1407 aPointLeftTop.setX(nTokenValue);
1408 break;
1409 case RTF_SHPTOP:
1410 aPointLeftTop.setY(nTokenValue);
1411 break;
1412 case RTF_SHPBOTTOM:
1413 aPointRightBottom.setY(nTokenValue);
1414 break;
1415 case RTF_SHPRIGHT:
1416 aPointRightBottom.setX(nTokenValue);
1417 break;
1418 case RTF_SN:
1419 nToken = GetNextToken();
1420 ASSERT(nToken==RTF_TEXTTOKEN, "expected name");
1421 sn=aToken;
1422 break;
1423 case RTF_SV:
1424 nToken = GetNextToken();
1425 if (nToken==RTF_TEXTTOKEN)
1427 if (sn.EqualsAscii("shapeType"))
1429 shapeType=aToken.ToInt32();
1431 } else if (sn.EqualsAscii("fFilled"))
1433 fFilled=aToken.ToInt32();
1435 } else if (sn.EqualsAscii("fLine"))
1437 fLine=aToken.ToInt32();
1438 } else if (sn.EqualsAscii("lineWidth"))
1440 lineWidth=aToken.ToInt32()/360;
1442 } else if (sn.EqualsAscii("fillColor"))
1444 sal_uInt32 nColor=aToken.ToInt32();
1445 fillColor=Color( (sal_uInt8)nColor, (sal_uInt8)( nColor >> 8 ), (sal_uInt8)( nColor >> 16 ) );
1446 }else if (sn.EqualsAscii("txflTextFlow"))
1448 txflTextFlow=aToken.ToInt32();
1452 break;
1453 case RTF_PICT:
1455 SvxRTFPictureType aPicType;
1456 bGrfValid=ReadBmpData( aGrf, aPicType );
1458 break;
1459 case RTF_SHPRSLT:
1460 if (shapeType!=1 && shapeType!=20 && shapeType!=75)
1462 ReadShpRslt();
1464 break;
1465 case RTF_SHPTXT:
1466 ReadShpTxt(shpTxt);
1467 bshpTxt=true;
1468 break;
1470 default:
1471 break;
1474 SkipToken(-1);
1476 switch(shapeType)
1478 case 202: /* Text Box */
1479 case 1: /* Rectangle */
1481 ::basegfx::B2DRange aRange(aPointLeftTop);
1482 aRange.expand(aPointRightBottom);
1484 if (txflTextFlow==2) {
1485 const ::basegfx::B2DPoint a(rotate(aRange.getMinimum(), aRange.getCenter()));
1486 const ::basegfx::B2DPoint b(rotate(aRange.getMaximum(), aRange.getCenter()));
1488 aRange.reset();
1489 aRange.expand(a);
1490 aRange.expand(b);
1493 const Rectangle aRect(FRound(aRange.getMinX()), FRound(aRange.getMinY()), FRound(aRange.getMaxX()), FRound(aRange.getMaxY()));
1494 SdrRectObj* pStroke = new SdrRectObj(aRect);
1495 pStroke->SetSnapRect(aRect);
1496 pDoc->GetOrCreateDrawModel(); // create model
1497 InsertShpObject(pStroke, this->nZOrder++);
1498 SfxItemSet aSet(pStroke->GetMergedItemSet());
1499 if (fFilled)
1501 aSet.Put(XFillStyleItem(XFILL_SOLID));
1502 aSet.Put(XFillColorItem( String(), fillColor ) );
1504 else
1506 aSet.Put(XFillStyleItem(XFILL_NONE));
1508 if (!fLine) {
1509 aSet.Put(XLineStyleItem(XLINE_NONE));
1510 } else {
1511 aSet.Put( XLineWidthItem( lineWidth/2 ) ); // lineWidth are in 1000th mm, seems that XLineWidthItem expects 1/2 the line width
1514 pStroke->SetMergedItemSet(aSet);
1515 if (bshpTxt) {
1516 SdrOutliner& rOutliner=pDoc->GetDrawModel()->GetDrawOutliner(pStroke);
1517 rOutliner.Clear();
1518 ByteString bs(shpTxt, RTL_TEXTENCODING_ASCII_US);
1519 SvMemoryStream aStream((sal_Char*)bs.GetBuffer(), bs.Len(), STREAM_READ);
1520 rOutliner.Read(aStream, String::CreateFromAscii(""), EE_FORMAT_RTF);
1521 OutlinerParaObject* pParaObject=rOutliner.CreateParaObject();
1522 pStroke->NbcSetOutlinerParaObject(pParaObject);
1523 //delete pParaObject;
1524 rOutliner.Clear();
1526 if (txflTextFlow==2) {
1527 long nAngle = 90;
1528 double a = nAngle*100*nPi180;
1529 pStroke->Rotate(pStroke->GetCurrentBoundRect().Center(), nAngle*100, sin(a), cos(a) );
1534 break;
1535 case 20: /* Line */
1537 ::basegfx::B2DPolygon aLine;
1538 aLine.append(aPointLeftTop);
1539 aLine.append(aPointRightBottom);
1541 SdrPathObj* pStroke = new SdrPathObj(OBJ_PLIN, ::basegfx::B2DPolyPolygon(aLine));
1542 //pStroke->SetSnapRect(aRect);
1544 InsertShpObject(pStroke, this->nZOrder++);
1545 SfxItemSet aSet(pStroke->GetMergedItemSet());
1546 if (!fLine) {
1547 aSet.Put(XLineStyleItem(XLINE_NONE));
1548 } else {
1549 aSet.Put( XLineWidthItem( lineWidth/2 ) ); // lineWidth are in 1000th mm, seems that XLineWidthItem expects 1/2 the line width
1552 pStroke->SetMergedItemSet(aSet);
1554 break;
1555 case 75 : /* Picture */
1556 if (bGrfValid) {
1557 ::basegfx::B2DRange aRange(aPointLeftTop);
1558 aRange.expand(aPointRightBottom);
1559 const Rectangle aRect(FRound(aRange.getMinX()), FRound(aRange.getMinY()), FRound(aRange.getMaxX()), FRound(aRange.getMaxY()));
1561 SdrRectObj* pStroke = new SdrGrafObj(aGrf);
1562 pStroke->SetSnapRect(aRect);
1564 InsertShpObject(pStroke, this->nZOrder++);
1569 extern void sw3io_ConvertFromOldField( SwDoc& rDoc, USHORT& rWhich,
1570 USHORT& rSubType, ULONG &rFmt,
1571 USHORT nVersion );
1573 USHORT SwRTFParser::ReadRevTbl()
1575 // rStr.Erase( 0 );
1576 int nNumOpenBrakets = 1, nToken; // die erste wurde schon vorher erkannt !!
1577 USHORT nAuthorTableIndex = 0;
1579 while( nNumOpenBrakets && IsParserWorking() )
1581 switch( nToken = GetNextToken() )
1583 case '}': --nNumOpenBrakets; break;
1584 case '{':
1586 if( RTF_IGNOREFLAG != GetNextToken() )
1587 nToken = SkipToken( -1 );
1588 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
1589 nToken = SkipToken( -2 );
1590 else
1592 ReadUnknownData();
1593 nToken = GetNextToken();
1594 if( '}' != nToken )
1595 eState = SVPAR_ERROR;
1596 break;
1598 ++nNumOpenBrakets;
1600 break;
1602 case RTF_TEXTTOKEN:
1603 aToken.EraseTrailingChars(';');
1605 USHORT nSWId = pDoc->InsertRedlineAuthor(aToken);
1606 // Store matchpair
1607 if( !pAuthorInfos )
1608 pAuthorInfos = new sw::util::AuthorInfos;
1609 sw::util::AuthorInfo* pAutorInfo = new sw::util::AuthorInfo( nAuthorTableIndex, nSWId );
1610 if( 0 == pAuthorInfos->Insert( pAutorInfo ) )
1611 delete pAutorInfo;
1613 aRevTbl.push_back(aToken);
1614 nAuthorTableIndex++;
1615 break;
1618 SkipToken( -1 );
1619 return nAuthorTableIndex;
1622 // #117910# simulate words behaviour of \keepn in table rows
1623 void fixKeepAndSplitAttributes(SwTableNode *pTableNode)
1625 ASSERT(pTableNode!=NULL, "no table node!");
1626 if (!pTableNode) return;
1627 SwDoc *pDoc=pTableNode->GetDoc();
1628 if (pTableNode==NULL) return;
1629 SwTable& rTable=pTableNode->GetTable();
1630 SwTableLines& rLns = rTable.GetTabLines();
1631 USHORT nLines=rLns.Count();
1632 if (nLines==0) return;
1633 // get first paragaph in left down-most box
1634 SwTableLine* pLastLine = rLns[ nLines-1 ];
1635 SwTableBox* pBox = pLastLine->GetTabBoxes()[ 0 ];
1636 ULONG iFirstParagraph=pBox->GetSttIdx()+1;
1637 SwTxtNode *pTxtNode=(SwTxtNode *)pDoc->GetNodes()[iFirstParagraph];
1638 SwFrmFmt* pFmt=rTable.GetFrmFmt();
1640 SwFmtLayoutSplit *pTableSplit=(SwFmtLayoutSplit *)pFmt->GetAttrSet().GetItem(RES_LAYOUT_SPLIT);
1641 BOOL isTableKeep = pTableSplit!=NULL && !pTableSplit->GetValue();
1642 SvxFmtKeepItem *pTableKeep=(SvxFmtKeepItem *)pFmt->GetAttrSet().GetItem(RES_KEEP);
1643 BOOL isTableKeepNext = pTableKeep!=NULL && pTableKeep->GetValue();
1644 SvxFmtKeepItem *pKeepNext = (SvxFmtKeepItem *)pTxtNode->GetSwAttrSet().GetItem(RES_KEEP);
1646 if (isTableKeepNext)
1648 if (nLines>2 && !isTableKeep)
1649 { // split
1650 SwTableLine* pSplitLine = rLns[ nLines-2 ];
1651 SwTableBox* pSplitBox = pSplitLine->GetTabBoxes()[ 0 ];
1652 SwNodeIndex aSplitIdx( *pSplitBox->GetSttNd() );
1653 pDoc->SplitTable( SwPosition(aSplitIdx), HEADLINE_NONE,
1654 !isTableKeep );
1655 SwTable& rSplitTable=aSplitIdx.GetNode().FindTableNode()->GetTable();
1656 aSplitIdx-=2;
1657 pDoc->GetNodes().Delete(aSplitIdx);
1658 pFmt=rSplitTable.GetFrmFmt();
1659 pFmt->ResetFmtAttr(RES_PAGEDESC);
1661 // set keep=1(i.e. split=0) attribut
1662 SwFmtLayoutSplit aSplit(0);
1663 SwAttrSet aNewSet(pFmt->GetAttrSet());
1664 aNewSet.Put(aSplit);
1665 pFmt->SetFmtAttr(aNewSet);
1667 else // !isTableKeepNext
1669 if (isTableKeep)
1671 SwNodeIndex aTmpIdx( *pBox->GetSttNd() );
1672 pDoc->SplitTable( SwPosition(aTmpIdx), HEADLINE_NONE, FALSE );
1673 SwTable& rSplitTable=aTmpIdx.GetNode().FindTableNode()->GetTable();
1674 aTmpIdx-=2;
1675 pDoc->GetNodes().Delete(aTmpIdx);
1676 pFmt=rSplitTable.GetFrmFmt();
1677 pFmt->ResetFmtAttr(RES_PAGEDESC);
1679 // set keep=0(i.e. split=1) attribut
1680 SwFmtLayoutSplit aSplit(1);
1681 SwAttrSet aNewSet(pFmt->GetAttrSet());
1682 aNewSet.Put(aSplit);
1683 pFmt->SetFmtAttr(aNewSet);
1685 // move keepnext attribtue from last paragraph to table
1686 if (pKeepNext!=NULL)
1688 SvxFmtKeepItem aNewKeepItem(pKeepNext->GetValue(), RES_KEEP);
1689 SwAttrSet aNewSet(pFmt->GetAttrSet());
1690 aNewSet.Put(aNewKeepItem);
1691 pFmt->SetFmtAttr(aNewSet);
1695 void SwRTFParser::NextToken( int nToken )
1697 USHORT eDateFmt;
1699 switch( nToken )
1701 case RTF_FOOTNOTE:
1702 //We can only insert a footnote if we're not inside a footnote. e.g.
1703 //#i7713#
1704 if (!mbIsFootnote)
1706 ReadHeaderFooter( nToken );
1707 SkipToken( -1 ); // Klammer wieder zurueck
1709 break;
1710 case RTF_SWG_PRTDATA:
1711 ReadPrtData();
1712 break;
1713 case RTF_XE:
1714 ReadXEField();
1715 break;
1716 case RTF_FIELD:
1717 ReadField();
1718 break;
1719 case RTF_SHPRSLT:
1720 ReadShpRslt();
1721 break;
1722 case RTF_DO:
1723 ReadDrawingObject();
1724 break;
1725 case RTF_SHP:
1726 ReadShapeObject();
1727 break;
1728 case RTF_SHPPICT:
1729 case RTF_PICT:
1730 ReadBitmapData();
1731 break;
1732 #ifdef READ_OLE_OBJECT
1733 case RTF_OBJECT:
1734 ReadOLEData();
1735 break;
1736 #endif
1737 case RTF_TROWD: ReadTable( nToken ); break;
1738 case RTF_PGDSCTBL:
1739 if( !IsNewDoc() )
1740 SkipPageDescTbl();
1741 else
1742 ReadPageDescTbl();
1743 break;
1744 case RTF_LISTTABLE: ReadListTable(); break;
1745 case RTF_LISTOVERRIDETABLE: ReadListOverrideTable(); break;
1747 case RTF_LISTTEXT:
1748 GetAttrSet().Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 ));
1749 SkipGroup();
1750 break;
1752 case RTF_PN:
1753 if( bNewNumList )
1754 SkipGroup();
1755 else
1757 bStyleTabValid = TRUE;
1758 if (SwNumRule* pRule = ReadNumSecLevel( nToken ))
1760 GetAttrSet().Put( SwNumRuleItem( pRule->GetName() ));
1762 if( SFX_ITEM_SET != GetAttrSet().GetItemState( FN_PARAM_NUM_LEVEL, FALSE ))
1763 GetAttrSet().Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 ));
1766 break;
1769 case RTF_BKMKSTART:
1770 if(RTF_TEXTTOKEN == GetNextToken())
1771 mpBookmarkStart = new BookmarkPosition(*pPam);
1772 else
1773 SkipToken(-1);
1775 SkipGroup();
1776 break;
1778 case RTF_BKMKEND:
1779 if(RTF_TEXTTOKEN == GetNextToken())
1781 const String& sBookmark = aToken;
1782 KeyCode aEmptyKeyCode;
1783 if (mpBookmarkStart)
1785 BookmarkPosition aBookmarkEnd(*pPam);
1786 SwPaM aBookmarkRegion( mpBookmarkStart->maMkNode, mpBookmarkStart->mnMkCntnt,
1787 aBookmarkEnd.maMkNode, aBookmarkEnd.mnMkCntnt);
1788 if (*mpBookmarkStart == aBookmarkEnd)
1789 aBookmarkRegion.DeleteMark();
1790 pDoc->getIDocumentMarkAccess()->makeMark(aBookmarkRegion, sBookmark, IDocumentMarkAccess::BOOKMARK);
1792 delete mpBookmarkStart, mpBookmarkStart = 0;
1794 else
1795 SkipToken(-1);
1797 SkipGroup();
1798 break;
1801 case RTF_PNSECLVL:{
1802 if( bNewNumList)
1803 SkipGroup();
1804 else
1805 ReadNumSecLevel( nToken );
1806 break;
1809 case RTF_PNTEXT:
1810 case RTF_NONSHPPICT:
1811 SkipGroup();
1812 break;
1814 case RTF_DEFFORMAT:
1815 case RTF_DEFTAB:
1816 case RTF_DEFLANG:
1817 // sind zwar Dok-Controls, werden aber manchmal auch vor der
1818 // Font/Style/Color-Tabelle gesetzt!
1819 SvxRTFParser::NextToken( nToken );
1820 break;
1822 case RTF_PAGE:
1823 if (pTableNode==NULL) { //#117410#: A \page command within a table is ignored by Word.
1824 if (lcl_UsedPara(*pPam))
1825 InsertPara();
1826 CheckInsNewTblLine();
1827 pDoc->Insert(*pPam, 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->Insert( *pPam, SwFmtPageDesc( pPgDsc ), 0);
1981 break;
1983 case RTF_COLUM:
1984 pDoc->Insert( *pPam, SvxFmtBreakItem( SVX_BREAK_COLUMN_BEFORE, RES_BREAK ), 0);
1985 break;
1987 case RTF_DXFRTEXT: // werden nur im Zusammenhang mit Flys ausgewertet
1988 case RTF_DFRMTXTX:
1989 case RTF_DFRMTXTY:
1990 break;
1992 case RTF_CHDATE: eDateFmt = DF_SHORT; goto SETCHDATEFIELD;
1993 case RTF_CHDATEA: eDateFmt = DF_SSYS; goto SETCHDATEFIELD;
1994 case RTF_CHDATEL: eDateFmt = DF_LSYS; goto SETCHDATEFIELD;
1995 SETCHDATEFIELD:
1997 USHORT nSubType = DATEFLD, nWhich = RES_DATEFLD;
1998 ULONG nFormat = eDateFmt;
1999 sw3io_ConvertFromOldField( *pDoc, nWhich, nSubType, nFormat, 0x0110 );
2001 SwDateTimeField aDateFld( (SwDateTimeFieldType*)
2002 pDoc->GetSysFldType( RES_DATETIMEFLD ), DATEFLD, nFormat);
2003 CheckInsNewTblLine();
2004 pDoc->Insert( *pPam, SwFmtFld( aDateFld ), 0);
2006 break;
2008 case RTF_CHTIME:
2010 USHORT nSubType = TIMEFLD, nWhich = RES_TIMEFLD;
2011 ULONG nFormat = TF_SSMM_24;
2012 sw3io_ConvertFromOldField( *pDoc, nWhich, nSubType, nFormat, 0x0110 );
2013 SwDateTimeField aTimeFld( (SwDateTimeFieldType*)
2014 pDoc->GetSysFldType( RES_DATETIMEFLD ), TIMEFLD, nFormat);
2015 CheckInsNewTblLine();
2016 pDoc->Insert( *pPam, SwFmtFld( aTimeFld ), 0);
2018 break;
2020 case RTF_CHPGN:
2022 SwPageNumberField aPageFld( (SwPageNumberFieldType*)
2023 pDoc->GetSysFldType( RES_PAGENUMBERFLD ),
2024 PG_RANDOM, SVX_NUM_ARABIC );
2025 CheckInsNewTblLine();
2026 pDoc->Insert( *pPam, SwFmtFld( aPageFld), 0);
2028 break;
2030 case RTF_CHFTN:
2031 bFootnoteAutoNum = TRUE;
2032 break;
2034 case RTF_NOFPAGES:
2035 if( IsNewDoc() && nTokenValue && -1 != nTokenValue )
2036 ((SwDocStat&)pDoc->GetDocStat()).nPage = (USHORT)nTokenValue;
2037 break;
2039 case RTF_NOFWORDS:
2040 if( IsNewDoc() && nTokenValue && -1 != nTokenValue )
2041 ((SwDocStat&)pDoc->GetDocStat()).nWord = (USHORT)nTokenValue;
2042 break;
2043 case RTF_NOFCHARS:
2044 if( IsNewDoc() && nTokenValue && -1 != nTokenValue )
2045 ((SwDocStat&)pDoc->GetDocStat()).nChar = (USHORT)nTokenValue;
2046 break;
2047 case RTF_LYTPRTMET:
2048 if (IsNewDoc())
2049 pDoc->set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, false);
2050 break;
2051 case RTF_U:
2053 CheckInsNewTblLine();
2054 if( nTokenValue )
2055 aToken = (sal_Unicode )nTokenValue;
2056 pDoc->Insert( *pPam, aToken, true );
2058 break;
2060 case RTF_USERPROPS:
2061 ReadUserProperties(); // #i28758 For now we don't support user properties
2062 break;
2064 // RTF_SUBENTRYINDEX
2066 default:
2067 switch( nToken & ~(0xff | RTF_SWGDEFS) )
2069 case RTF_DOCFMT:
2070 ReadDocControls( nToken );
2071 break;
2072 case RTF_SECTFMT:
2073 ReadSectControls( nToken );
2074 break;
2075 case RTF_APOCTL:
2076 if (nReadFlyDepth < 10)
2078 nReadFlyDepth++;
2079 ReadFly( nToken );
2080 nReadFlyDepth--;
2082 break;
2084 case RTF_BRDRDEF | RTF_TABLEDEF:
2085 case RTF_SHADINGDEF | RTF_TABLEDEF:
2086 case RTF_TABLEDEF:
2087 ReadTable( nToken );
2088 break;
2090 case RTF_INFO:
2091 ReadInfo();
2092 break;
2094 default:
2095 if( USHRT_MAX != nInsTblRow &&
2096 (nInsTblRow > GetOpenBrakets() || IsPardTokenRead() ))
2097 nInsTblRow = USHRT_MAX;
2099 SvxRTFParser::NextToken( nToken );
2100 break;
2103 if( USHRT_MAX != nInsTblRow &&
2104 (nInsTblRow > GetOpenBrakets() || IsPardTokenRead() ))
2105 nInsTblRow = USHRT_MAX;
2110 void SwRTFParser::InsertText()
2112 bContainsPara = false;
2113 // dann fuege den String ein, ohne das Attribute am Ende
2114 // aufgespannt werden.
2115 CheckInsNewTblLine();
2117 if(pRedlineInsert)
2118 mpRedlineStack->open(*pPam->GetPoint(), *pRedlineInsert);
2119 if(pRedlineDelete)
2120 mpRedlineStack->open(*pPam->GetPoint(), *pRedlineDelete);
2122 pDoc->Insert( *pPam, aToken, true );
2124 if(pRedlineDelete)
2126 mpRedlineStack->close(*pPam->GetPoint(), pRedlineDelete->eType);
2129 if(pRedlineInsert)
2131 mpRedlineStack->close(*pPam->GetPoint(), pRedlineInsert->eType);
2138 void SwRTFParser::InsertPara()
2140 bContainsPara = true;
2141 CheckInsNewTblLine();
2142 pDoc->AppendTxtNode(*pPam->GetPoint());
2144 // setze das default Style
2145 if( !bStyleTabValid )
2146 MakeStyleTab();
2148 SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 );
2149 if( !pColl )
2150 pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
2151 pDoc->SetTxtFmtColl( *pPam, pColl );
2153 ::SetProgressState( rInput.Tell(), pDoc->GetDocShell() );
2158 void SwRTFParser::MovePos( int bForward )
2160 if( bForward )
2161 pPam->Move( fnMoveForward );
2162 else
2163 pPam->Move( fnMoveBackward );
2166 int SwRTFParser::IsEndPara( SvxNodeIdx* pNd, xub_StrLen nCnt ) const
2168 SwCntntNode *pNode = pDoc->GetNodes()[pNd->GetIdx()]->GetCntntNode();
2169 return pNode && pNode->Len() == nCnt;
2172 bool SwRTFParser::UncompressableStackEntry(const SvxRTFItemStackType &rSet)
2173 const
2176 #i21961#
2177 Seeing as CHARFMT sets all the properties of the charfmt itself, its not
2178 good enough to just see it as a single property from the point of
2179 compressing property sets. If bold and charfmt are in a child, and bold is
2180 in the parent, removing bold from the child will not result in the same
2181 thing, if the charfmt removes bold itself for example
2183 bool bRet = false;
2184 if (rSet.GetAttrSet().Count())
2187 if (SFX_ITEM_SET ==
2188 rSet.GetAttrSet().GetItemState(RES_TXTATR_CHARFMT, FALSE))
2190 bRet = true;
2193 return bRet;
2196 void SwRTFParser::SetEndPrevPara( SvxNodeIdx*& rpNodePos, xub_StrLen& rCntPos )
2198 SwNodeIndex aIdx( pPam->GetPoint()->nNode );
2199 SwCntntNode* pNode = pDoc->GetNodes().GoPrevious( &aIdx );
2200 if( !pNode )
2202 ASSERT( FALSE, "keinen vorherigen ContentNode gefunden" );
2205 rpNodePos = new SwNodeIdx( aIdx );
2206 rCntPos = pNode->Len();
2209 void SwRTFParser::SetAttrInDoc( SvxRTFItemStackType &rSet )
2211 ULONG nSNd = rSet.GetSttNodeIdx(), nENd = rSet.GetEndNodeIdx();
2212 xub_StrLen nSCnt = rSet.GetSttCnt(), nECnt = rSet.GetEndCnt();
2214 SwPaM aPam( *pPam->GetPoint() );
2216 #ifndef PRODUCT
2217 ASSERT( nSNd <= nENd, "Start groesser als Ende" );
2218 SwNode* pDebugNd = pDoc->GetNodes()[ nSNd ];
2219 ASSERT( pDebugNd->IsCntntNode(), "Start kein ContentNode" );
2220 pDebugNd = pDoc->GetNodes()[ nENd ];
2221 ASSERT( pDebugNd->IsCntntNode(), "Ende kein ContentNode" );
2222 #endif
2224 SwCntntNode* pCNd = pDoc->GetNodes()[ nSNd ]->GetCntntNode();
2225 aPam.GetPoint()->nNode = nSNd;
2226 aPam.GetPoint()->nContent.Assign( pCNd, nSCnt );
2227 aPam.SetMark();
2228 if( nENd == nSNd )
2229 aPam.GetPoint()->nContent = nECnt;
2230 else
2232 aPam.GetPoint()->nNode = nENd;
2233 pCNd = aPam.GetCntntNode();
2234 aPam.GetPoint()->nContent.Assign( pCNd, nECnt );
2237 // setze ueber den Bereich das entsprechende Style
2238 if( rSet.StyleNo() )
2240 // setze jetzt das Style
2241 if( !bStyleTabValid )
2242 MakeStyleTab();
2243 SwTxtFmtColl* pColl = aTxtCollTbl.Get( rSet.StyleNo() );
2244 if( pColl )
2245 pDoc->SetTxtFmtColl( aPam, pColl, false );
2248 const SfxPoolItem* pItem;
2249 const SfxPoolItem* pCharFmt;
2250 if (rSet.GetAttrSet().Count() )
2253 // falls eine Zeichenvorlage im Set steht, deren Attribute
2254 // aus dem Set loeschen. Sonst sind diese doppelt, was man ja
2255 // nicht will.
2256 if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(
2257 RES_TXTATR_CHARFMT, FALSE, &pCharFmt ) &&
2258 ((SwFmtCharFmt*)pCharFmt)->GetCharFmt() )
2260 const String& rName = ((SwFmtCharFmt*)pCharFmt)->GetCharFmt()->GetName();
2261 SvxRTFStyleType* pStyle = GetStyleTbl().First();
2262 do {
2263 if( pStyle->bIsCharFmt && pStyle->sName == rName )
2265 // alle Attribute, die schon vom Style definiert sind, aus dem
2266 // akt. AttrSet entfernen
2267 SfxItemSet &rAttrSet = rSet.GetAttrSet(),
2268 &rStyleSet = pStyle->aAttrSet;
2269 SfxItemIter aIter( rAttrSet );
2270 USHORT nWhich = aIter.GetCurItem()->Which();
2271 while( TRUE )
2273 const SfxPoolItem* pI;
2274 if( SFX_ITEM_SET == rStyleSet.GetItemState(
2275 nWhich, FALSE, &pI ) && *pI == *aIter.GetCurItem())
2276 rAttrSet.ClearItem( nWhich ); // loeschen
2278 if( aIter.IsAtEnd() )
2279 break;
2280 nWhich = aIter.NextItem()->Which();
2282 break;
2284 } while( 0 != (pStyle = GetStyleTbl().Next()) );
2286 pDoc->Insert(aPam, *pCharFmt, 0);
2287 rSet.GetAttrSet().ClearItem(RES_TXTATR_CHARFMT); //test hack
2289 if (rSet.GetAttrSet().Count())
2291 // dann setze ueber diesen Bereich die Attrbiute
2292 SetSwgValues(rSet.GetAttrSet());
2293 pDoc->Insert(aPam, rSet.GetAttrSet(), nsSetAttrMode::SETATTR_DONTCHGNUMRULE);
2297 if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(
2298 FN_PARAM_NUM_LEVEL, FALSE, &pItem ))
2300 // dann ueber den Bereich an den Nodes das NodeNum setzen
2301 for( ULONG n = nSNd; n <= nENd; ++n )
2303 SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode();
2304 if( pTxtNd )
2306 pTxtNd->SetAttrListLevel((BYTE) ((SfxUInt16Item*)pItem)->GetValue());
2307 // Update vom LR-Space abschalten?
2312 if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(
2313 RES_PARATR_NUMRULE, FALSE, &pItem ))
2315 const SwNumRule* pRule = pDoc->FindNumRulePtr(
2316 ((SwNumRuleItem*)pItem)->GetValue() );
2317 if( pRule && ( pRule->IsContinusNum() || !bNewNumList ))
2319 // diese Rule hat keinen Level, also muss die Einrueckung
2320 // erhalten bleiben!
2321 // dann ueber den Bereich an den Nodes das Flag zuruecksetzen
2322 for( ULONG n = nSNd; n <= nENd; ++n )
2324 SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode();
2325 if( pTxtNd )
2327 // Update vom LR-Space abschalten
2328 pTxtNd->SetNumLSpace( FALSE );
2334 bool bNoNum = true;
2335 if (
2336 (SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(RES_PARATR_NUMRULE))
2337 || (SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(FN_PARAM_NUM_LEVEL))
2340 bNoNum = false;
2343 if (bNoNum)
2345 for( ULONG n = nSNd; n <= nENd; ++n )
2347 SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode();
2348 if( pTxtNd )
2350 pTxtNd->SetAttr(
2351 *GetDfltAttr(RES_PARATR_NUMRULE));
2357 DocPageInformation::DocPageInformation()
2358 : maBox( RES_BOX ),
2359 mnPaperw(12240), mnPaperh(15840), mnMargl(1800), mnMargr(1800),
2360 mnMargt(1440), mnMargb(1440), mnGutter(0), mnPgnStart(1), mbFacingp(false),
2361 mbLandscape(false), mbRTLdoc(false)
2365 SectPageInformation::SectPageInformation(const DocPageInformation &rDoc)
2366 : maBox(rDoc.maBox), mpTitlePageHdFt(0), mpPageHdFt(0),
2367 mnPgwsxn(rDoc.mnPaperw), mnPghsxn(rDoc.mnPaperh), mnMarglsxn(rDoc.mnMargl),
2368 mnMargrsxn(rDoc.mnMargr), mnMargtsxn(rDoc.mnMargt),
2369 mnMargbsxn(rDoc.mnMargb), mnGutterxsn(rDoc.mnGutter), mnHeadery(720),
2370 mnFootery(720), mnPgnStarts(rDoc.mnPgnStart), mnCols(1), mnColsx(720),
2371 mnStextflow(rDoc.mbRTLdoc ? 3 : 0), mnBkc(2), mbLndscpsxn(rDoc.mbLandscape),
2372 mbTitlepg(false), mbFacpgsxn(rDoc.mbFacingp), mbRTLsection(rDoc.mbRTLdoc),
2373 mbPgnrestart(false), mbTitlePageHdFtUsed(false), mbPageHdFtUsed(false)
2377 SectPageInformation::SectPageInformation(const SectPageInformation &rSect)
2378 : maColumns(rSect.maColumns), maBox(rSect.maBox),
2379 maNumType(rSect.maNumType), mpTitlePageHdFt(rSect.mpTitlePageHdFt),
2380 mpPageHdFt(rSect.mpPageHdFt), mnPgwsxn(rSect.mnPgwsxn),
2381 mnPghsxn(rSect.mnPghsxn), mnMarglsxn(rSect.mnMarglsxn),
2382 mnMargrsxn(rSect.mnMargrsxn), mnMargtsxn(rSect.mnMargtsxn),
2383 mnMargbsxn(rSect.mnMargbsxn), mnGutterxsn(rSect.mnGutterxsn),
2384 mnHeadery(rSect.mnHeadery), mnFootery(rSect.mnFootery),
2385 mnPgnStarts(rSect.mnPgnStarts), mnCols(rSect.mnCols),
2386 mnColsx(rSect.mnColsx), mnStextflow(rSect.mnStextflow), mnBkc(rSect.mnBkc),
2387 mbLndscpsxn(rSect.mbLndscpsxn), mbTitlepg(rSect.mbTitlepg),
2388 mbFacpgsxn(rSect.mbFacpgsxn), mbRTLsection(rSect.mbRTLsection),
2389 mbPgnrestart(rSect.mbPgnrestart),
2390 mbTitlePageHdFtUsed(rSect.mbTitlePageHdFtUsed),
2391 mbPageHdFtUsed(rSect.mbPageHdFtUsed)
2395 rtfSection::rtfSection(const SwPosition &rPos,
2396 const SectPageInformation &rPageInfo)
2397 : maStart(rPos.nNode), maPageInfo(rPageInfo), mpSection(0), mpTitlePage(0),
2398 mpPage(0)
2402 void rtfSections::push_back(const rtfSection &rSect)
2404 if (!maSegments.empty() && (maSegments.back().maStart == rSect.maStart))
2405 maSegments.pop_back();
2406 maSegments.push_back(rSect);
2409 // lese alle Dokument-Controls ein
2410 void SwRTFParser::SetPageInformationAsDefault(const DocPageInformation &rInfo)
2412 //If we are at the beginning of the document then start the document with
2413 //a segment with these properties. See #i14982# for this requirement
2414 rtfSection aSect(*pPam->GetPoint(), SectPageInformation(rInfo));
2415 if (maSegments.empty() || (maSegments.back().maStart == aSect.maStart))
2416 maSegments.push_back(aSect);
2418 if (!bSwPageDesc && IsNewDoc())
2420 SwFmtFrmSize aFrmSize(ATT_FIX_SIZE, rInfo.mnPaperw, rInfo.mnPaperh);
2422 SvxLRSpaceItem aLR( static_cast< USHORT >(rInfo.mnMargl), static_cast< USHORT >(rInfo.mnMargr), 0, 0, RES_LR_SPACE );
2423 SvxULSpaceItem aUL( static_cast< USHORT >(rInfo.mnMargt), static_cast< USHORT >(rInfo.mnMargb), RES_UL_SPACE );
2425 UseOnPage eUseOn;
2426 if (rInfo.mbFacingp)
2427 eUseOn = UseOnPage(nsUseOnPage::PD_MIRROR | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE);
2428 else
2429 eUseOn = UseOnPage(nsUseOnPage::PD_ALL | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE);
2431 USHORT nPgStart = static_cast< USHORT >(rInfo.mnPgnStart);
2433 SvxFrameDirectionItem aFrmDir(rInfo.mbRTLdoc ?
2434 FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR);
2436 // direkt an der Standartseite drehen
2437 SwPageDesc& rPg = pDoc->_GetPageDesc( 0 );
2438 rPg.WriteUseOn( eUseOn );
2440 if (rInfo.mbLandscape)
2441 rPg.SetLandscape(true);
2443 SwFrmFmt &rFmt1 = rPg.GetMaster(), &rFmt2 = rPg.GetLeft();
2445 rFmt1.SetFmtAttr( aFrmSize ); rFmt2.SetFmtAttr( aFrmSize );
2446 rFmt1.SetFmtAttr( aLR ); rFmt2.SetFmtAttr( aLR );
2447 rFmt1.SetFmtAttr( aUL ); rFmt2.SetFmtAttr( aUL );
2448 rFmt1.SetFmtAttr( aFrmDir ); rFmt2.SetFmtAttr( aFrmDir );
2450 // StartNummer der Seiten setzen
2451 if (nPgStart != 1)
2453 SwFmtPageDesc aPgDsc( &rPg );
2454 aPgDsc.SetNumOffset( nPgStart );
2455 pDoc->Insert( *pPam, aPgDsc, 0 );
2460 void SwRTFParser::SetBorderLine(SvxBoxItem& rBox, sal_uInt16 nLine)
2462 int bWeiter = true;
2463 short nLineThickness = 1;
2464 short nPageDistance = 0;
2465 BYTE nCol = 0;
2466 short nIdx = 0;
2468 int nToken = GetNextToken();
2469 do {
2470 switch( nToken )
2472 case RTF_BRDRS:
2473 nIdx = 1;
2474 break;
2476 case RTF_BRDRDB:
2477 nIdx = 3;
2478 break;
2480 case RTF_BRDRTRIPLE:
2481 nIdx = 10;
2482 break;
2484 case RTF_BRDRTNTHSG:
2485 nIdx = 11;
2486 break;
2488 case RTF_BRDRTHTNSG:
2489 nIdx = 12;
2490 break;
2492 case RTF_BRDRTNTHTNSG:
2493 nIdx = 13;
2494 break;
2496 case RTF_BRDRTNTHMG:
2497 nIdx = 14;
2498 break;
2500 case RTF_BRDRTHTNMG:
2501 nIdx = 15;
2502 break;
2504 case RTF_BRDRTNTHTNMG:
2505 nIdx = 16;
2506 break;
2508 case RTF_BRDRTNTHLG:
2509 nIdx = 17;
2510 break;
2512 case RTF_BRDRTHTNLG:
2513 nIdx = 18;
2514 break;
2516 case RTF_BRDRTNTHTNLG:
2517 nIdx = 19;
2518 break;
2520 case RTF_BRDRWAVY:
2521 nIdx = 20;
2522 break;
2524 case RTF_BRDRWAVYDB:
2525 nIdx = 21;
2526 break;
2528 case RTF_BRDREMBOSS:
2529 nIdx = 24;
2530 break;
2532 case RTF_BRDRENGRAVE:
2533 nIdx = 25;
2534 break;
2536 case RTF_BRSP:
2537 nPageDistance = static_cast< short >(nTokenValue);
2538 break;
2540 case RTF_BRDRDOT: // SO does not have dashed or dotted lines
2541 case RTF_BRDRDASH:
2542 case RTF_BRDRDASHSM:
2543 case RTF_BRDRDASHD:
2544 case RTF_BRDRDASHDD:
2545 case RTF_BRDRDASHDOTSTR:
2546 case RTF_BRDRSH: // shading not supported
2547 case RTF_BRDRCF: // colors not supported
2548 break;
2550 case RTF_BRDRW:
2551 nLineThickness = static_cast< short >(nTokenValue);
2552 break;
2553 default:
2554 bWeiter = false;
2555 SkipToken(-1);
2556 break;
2558 if (bWeiter)
2559 nToken = GetNextToken();
2560 } while (bWeiter && IsParserWorking());
2562 GetLineIndex(rBox, nLineThickness, nPageDistance, nCol, nIdx, nLine, nLine, 0);
2565 // lese alle Dokument-Controls ein
2566 void SwRTFParser::ReadDocControls( int nToken )
2568 int bWeiter = true;
2570 SwFtnInfo aFtnInfo;
2571 SwEndNoteInfo aEndInfo;
2572 bool bSetHyph = false;
2574 BOOL bEndInfoChgd = FALSE, bFtnInfoChgd = FALSE;
2576 do {
2577 USHORT nValue = USHORT( nTokenValue );
2578 switch( nToken )
2580 case RTF_RTLDOC:
2581 maPageDefaults.mbRTLdoc = true;
2582 break;
2583 case RTF_LTRDOC:
2584 maPageDefaults.mbRTLdoc = false;
2585 break;
2586 case RTF_LANDSCAPE:
2587 maPageDefaults.mbLandscape = true;
2588 break;
2589 case RTF_PAPERW:
2590 if( 0 < nTokenValue )
2591 maPageDefaults.mnPaperw = nTokenValue;
2592 break;
2593 case RTF_PAPERH:
2594 if( 0 < nTokenValue )
2595 maPageDefaults.mnPaperh = nTokenValue;
2596 break;
2597 case RTF_MARGL:
2598 if( 0 <= nTokenValue )
2599 maPageDefaults.mnMargl = nTokenValue;
2600 break;
2601 case RTF_MARGR:
2602 if( 0 <= nTokenValue )
2603 maPageDefaults.mnMargr = nTokenValue;
2604 break;
2605 case RTF_MARGT:
2606 if( 0 <= nTokenValue )
2607 maPageDefaults.mnMargt = nTokenValue;
2608 break;
2609 case RTF_MARGB:
2610 if( 0 <= nTokenValue )
2611 maPageDefaults.mnMargb = nTokenValue;
2612 break;
2613 case RTF_FACINGP:
2614 maPageDefaults.mbFacingp = true;
2615 break;
2616 case RTF_PGNSTART:
2617 maPageDefaults.mnPgnStart = nTokenValue;
2618 break;
2619 case RTF_ENDDOC:
2620 case RTF_ENDNOTES:
2621 aFtnInfo.ePos = FTNPOS_CHAPTER; bFtnInfoChgd = TRUE;
2622 break;
2623 case RTF_FTNTJ:
2624 case RTF_FTNBJ:
2625 aFtnInfo.ePos = FTNPOS_PAGE; bFtnInfoChgd = TRUE;
2626 break;
2628 case RTF_AENDDOC:
2629 case RTF_AENDNOTES:
2630 case RTF_AFTNTJ:
2631 case RTF_AFTNBJ:
2632 case RTF_AFTNRESTART:
2633 case RTF_AFTNRSTCONT:
2634 break; // wir kenn nur am Doc Ende und Doc weite Num.!
2636 case RTF_FTNSTART:
2637 if( nValue )
2639 aFtnInfo.nFtnOffset = nValue-1;
2640 bFtnInfoChgd = TRUE;
2642 break;
2643 case RTF_AFTNSTART:
2644 if( nValue )
2646 aEndInfo.nFtnOffset = nValue-1;
2647 bEndInfoChgd = TRUE;
2649 break;
2650 case RTF_FTNRSTPG:
2651 aFtnInfo.eNum = FTNNUM_PAGE; bFtnInfoChgd = TRUE;
2652 break;
2653 case RTF_FTNRESTART:
2654 aFtnInfo.eNum = FTNNUM_CHAPTER; bFtnInfoChgd = TRUE;
2655 break;
2656 case RTF_FTNRSTCONT:
2657 aFtnInfo.eNum = FTNNUM_DOC; bFtnInfoChgd = TRUE;
2658 break;
2660 case RTF_FTNNAR:
2661 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ARABIC); bFtnInfoChgd = TRUE; break;
2662 case RTF_FTNNALC:
2663 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER_N); bFtnInfoChgd = TRUE; break;
2664 case RTF_FTNNAUC:
2665 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_UPPER_LETTER_N); bFtnInfoChgd = TRUE; break;
2666 case RTF_FTNNRLC:
2667 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER); bFtnInfoChgd = TRUE; break;
2668 case RTF_FTNNRUC:
2669 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_UPPER); bFtnInfoChgd = TRUE; break;
2670 case RTF_FTNNCHI:
2671 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL); bFtnInfoChgd = TRUE; break;
2673 case RTF_AFTNNAR:
2674 aEndInfo.aFmt.SetNumberingType(SVX_NUM_ARABIC); bEndInfoChgd = TRUE; break;
2675 case RTF_AFTNNALC:
2676 aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER_N);
2677 bEndInfoChgd = TRUE;
2678 break;
2679 case RTF_AFTNNAUC:
2680 aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_UPPER_LETTER_N);
2681 bEndInfoChgd = TRUE;
2682 break;
2683 case RTF_AFTNNRLC:
2684 aEndInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER);
2685 bEndInfoChgd = TRUE;
2686 break;
2687 case RTF_AFTNNRUC:
2688 aEndInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_UPPER);
2689 bEndInfoChgd = TRUE;
2690 break;
2691 case RTF_AFTNNCHI:
2692 aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
2693 bEndInfoChgd = TRUE;
2694 break;
2695 case RTF_HYPHAUTO:
2696 if (nTokenValue)
2697 bSetHyph = true;
2698 //FOO//
2699 break;
2700 case RTF_PGBRDRT:
2701 SetBorderLine(maPageDefaults.maBox, BOX_LINE_TOP);
2702 break;
2704 case RTF_PGBRDRB:
2705 SetBorderLine(maPageDefaults.maBox, BOX_LINE_BOTTOM);
2706 break;
2708 case RTF_PGBRDRL:
2709 SetBorderLine(maPageDefaults.maBox, BOX_LINE_LEFT);
2710 break;
2712 case RTF_PGBRDRR:
2713 SetBorderLine(maPageDefaults.maBox, BOX_LINE_RIGHT);
2714 break;
2716 case '{':
2718 short nSkip = 0;
2719 if( RTF_IGNOREFLAG != GetNextToken() )
2720 nSkip = -1;
2721 else if( RTF_DOCFMT != (( nToken = GetNextToken() )
2722 & ~(0xff | RTF_SWGDEFS)) )
2723 nSkip = -2;
2724 else
2726 SkipGroup(); // erstmal komplett ueberlesen
2727 // ueberlese noch die schliessende Klammer
2728 GetNextToken();
2730 if( nSkip )
2732 SkipToken( nSkip ); // Ignore wieder zurueck
2733 bWeiter = FALSE;
2736 break;
2738 default:
2739 if( RTF_DOCFMT == (nToken & ~(0xff | RTF_SWGDEFS)) ||
2740 RTF_UNKNOWNCONTROL == nToken )
2741 SvxRTFParser::NextToken( nToken );
2742 else
2743 bWeiter = FALSE;
2744 break;
2746 if( bWeiter )
2747 nToken = GetNextToken();
2748 } while( bWeiter && IsParserWorking() );
2750 if (IsNewDoc())
2752 if( bEndInfoChgd )
2753 pDoc->SetEndNoteInfo( aEndInfo );
2754 if( bFtnInfoChgd )
2755 pDoc->SetFtnInfo( aFtnInfo );
2758 if (!bSwPageDesc)
2760 SetPageInformationAsDefault(maPageDefaults);
2762 MakeStyleTab();
2764 SwTxtFmtColl* pColl = aTxtCollTbl.Get(0);
2765 if (!pColl)
2767 pColl = pDoc->GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false );
2770 ASSERT(pColl, "impossible to have no standard style");
2772 if (pColl)
2774 if (
2775 IsNewDoc() && bSetHyph &&
2776 SFX_ITEM_SET != pColl->GetItemState(RES_PARATR_HYPHENZONE,
2777 false)
2780 pColl->SetFmtAttr(SvxHyphenZoneItem(true, RES_PARATR_HYPHENZONE));
2783 pDoc->SetTxtFmtColl( *pPam, pColl );
2787 SkipToken( -1 );
2790 void SwRTFParser::MakeStyleTab()
2792 // dann erzeuge aus der SvxStyle-Tabelle die Swg-Collections
2793 if( GetStyleTbl().Count() )
2795 USHORT nValidOutlineLevels = 0;
2796 if( !IsNewDoc() )
2798 // search all outlined collections
2799 //BYTE nLvl;
2800 const SwTxtFmtColls& rColls = *pDoc->GetTxtFmtColls();
2801 for( USHORT n = rColls.Count(); n; )
2802 //if( MAXLEVEL > (nLvl = rColls[ --n ]->GetOutlineLevel() ))//#outline level,zhaojianwei
2803 // nValidOutlineLevels |= 1 << nLvl;
2804 if( rColls[ --n ]->IsAssignedToListLevelOfOutlineStyle())
2805 nValidOutlineLevels |= 1 << rColls[ n ]->GetAssignedOutlineStyleLevel();//<-end,zhaojianwei
2808 SvxRTFStyleType* pStyle = GetStyleTbl().First();
2809 do {
2810 USHORT nNo = USHORT( GetStyleTbl().GetCurKey() );
2811 if( pStyle->bIsCharFmt )
2813 if( !aCharFmtTbl.Get( nNo ) )
2814 // existiert noch nicht, also anlegen
2815 MakeCharStyle( nNo, *pStyle );
2817 else if( !aTxtCollTbl.Get( nNo ) )
2819 // existiert noch nicht, also anlegen
2820 MakeStyle( nNo, *pStyle );
2823 } while( 0 != (pStyle = GetStyleTbl().Next()) );
2824 bStyleTabValid = TRUE;
2828 BOOL lcl_SetFmtCol( SwFmt& rFmt, USHORT nCols, USHORT nColSpace,
2829 const SvUShorts& rColumns )
2831 BOOL bSet = FALSE;
2832 if( nCols && USHRT_MAX != nCols )
2834 SwFmtCol aCol;
2835 if( USHRT_MAX == nColSpace )
2836 nColSpace = 720;
2838 aCol.Init( nCols, nColSpace, USHRT_MAX );
2839 if( nCols == ( rColumns.Count() / 2 ) )
2841 aCol._SetOrtho( FALSE );
2842 USHORT nWishWidth = 0, nHalfPrev = 0;
2843 for( USHORT n = 0, i = 0; n < rColumns.Count(); n += 2, ++i )
2845 SwColumn* pCol = aCol.GetColumns()[ i ];
2846 pCol->SetLeft( nHalfPrev );
2847 USHORT nSp = rColumns[ n+1 ];
2848 nHalfPrev = nSp / 2;
2849 pCol->SetRight( nSp - nHalfPrev );
2850 pCol->SetWishWidth( rColumns[ n ] +
2851 pCol->GetLeft() + pCol->GetRight() );
2852 nWishWidth = nWishWidth + pCol->GetWishWidth();
2854 aCol.SetWishWidth( nWishWidth );
2856 rFmt.SetFmtAttr( aCol );
2857 bSet = TRUE;
2859 return bSet;
2862 void SwRTFParser::DoHairyWriterPageDesc(int nToken)
2864 int bWeiter = TRUE;
2865 do {
2866 if( '{' == nToken )
2868 switch( nToken = GetNextToken() )
2870 case RTF_IGNOREFLAG:
2871 if( RTF_SECTFMT != (( nToken = GetNextToken() )
2872 & ~(0xff | RTF_SWGDEFS)) )
2874 SkipToken( -2 ); // Ignore und Token wieder zurueck
2875 bWeiter = FALSE;
2876 break;
2878 // kein break, Gruppe ueberspringen
2880 case RTF_FOOTER:
2881 case RTF_HEADER:
2882 case RTF_FOOTERR:
2883 case RTF_HEADERR:
2884 case RTF_FOOTERL:
2885 case RTF_HEADERL:
2886 case RTF_FOOTERF:
2887 case RTF_HEADERF:
2888 SkipGroup(); // erstmal komplett ueberlesen
2889 // ueberlese noch die schliessende Klammer
2890 GetNextToken();
2891 break;
2893 default:
2894 SkipToken( -1 ); // Ignore wieder zurueck
2895 bWeiter = FALSE;
2896 break;
2899 else if( RTF_SECTFMT == (nToken & ~(0xff | RTF_SWGDEFS)) ||
2900 RTF_UNKNOWNCONTROL == nToken )
2901 SvxRTFParser::NextToken( nToken );
2902 else
2903 bWeiter = FALSE;
2904 if( bWeiter )
2905 nToken = GetNextToken();
2906 } while( bWeiter && IsParserWorking() );
2907 SkipToken( -1 ); // letztes Token wieder zurueck
2908 return;
2911 void SwRTFParser::ReadSectControls( int nToken )
2913 //this is some hairy stuff to try and retain writer style page descriptors
2914 //in rtf, almost certainy a bad idea, but we've inherited it, so here it
2915 //stays
2916 if (bInPgDscTbl)
2918 DoHairyWriterPageDesc(nToken);
2919 return;
2922 ASSERT(!maSegments.empty(), "suspicious to have a section with no "
2923 "page info, though probably legal");
2924 if (maSegments.empty())
2926 maSegments.push_back(rtfSection(*pPam->GetPoint(),
2927 SectPageInformation(maPageDefaults)));
2930 SectPageInformation aNewSection(maSegments.back().maPageInfo);
2932 bool bNewSection = false;
2933 bool bNewSectionHeader = false;
2934 const SwFmtHeader* _pKeepHeader = NULL;
2935 const SwFmtFooter* _pKeepFooter = NULL;
2936 int bWeiter = true;
2937 bool bKeepFooter = false;
2938 do {
2939 USHORT nValue = USHORT( nTokenValue );
2940 switch( nToken )
2942 case RTF_SECT:
2943 bNewSection = true;
2944 bForceNewTable = true; // #117882#
2945 break;
2946 case RTF_SECTD: {
2947 //Reset to page defaults
2948 SwPageDesc* oldPageDesc=aNewSection.mpPageHdFt;
2949 aNewSection = SectPageInformation(maPageDefaults);
2950 aNewSection.mpPageHdFt=oldPageDesc;
2951 _pKeepHeader = NULL;
2952 _pKeepFooter = NULL;
2953 } break;
2954 case RTF_PGWSXN:
2955 if (0 < nTokenValue)
2956 aNewSection.mnPgwsxn = nTokenValue;
2957 break;
2958 case RTF_PGHSXN:
2959 if (0 < nTokenValue)
2960 aNewSection.mnPghsxn = nTokenValue;
2961 break;
2962 case RTF_MARGLSXN:
2963 if (0 <= nTokenValue)
2964 aNewSection.mnMarglsxn = nTokenValue;
2965 break;
2966 case RTF_MARGRSXN:
2967 if (0 <= nTokenValue)
2968 aNewSection.mnMargrsxn = nTokenValue;
2969 break;
2970 case RTF_MARGTSXN:
2971 if (0 <= nTokenValue)
2972 aNewSection.mnMargtsxn = nTokenValue;
2973 break;
2974 case RTF_MARGBSXN:
2975 if (0 <= nTokenValue)
2976 aNewSection.mnMargbsxn = nTokenValue;
2977 break;
2978 case RTF_FACPGSXN:
2979 aNewSection.mbFacpgsxn = true;
2980 break;
2981 case RTF_HEADERY:
2982 aNewSection.mnHeadery = nTokenValue;
2983 break;
2984 case RTF_FOOTERY:
2985 aNewSection.mnFootery = nTokenValue;
2986 break;
2987 case RTF_LNDSCPSXN:
2988 aNewSection.mbLndscpsxn = true;
2989 break;
2990 case RTF_PGNSTARTS:
2991 aNewSection.mnPgnStarts = nTokenValue;
2992 break;
2993 case RTF_PGNDEC:
2994 aNewSection.maNumType.SetNumberingType(SVX_NUM_ARABIC);
2995 break;
2996 case RTF_PGNUCRM:
2997 aNewSection.maNumType.SetNumberingType(SVX_NUM_ROMAN_UPPER);
2998 break;
2999 case RTF_PGNLCRM:
3000 aNewSection.maNumType.SetNumberingType(SVX_NUM_ROMAN_LOWER);
3001 break;
3002 case RTF_PGNUCLTR:
3003 aNewSection.maNumType.SetNumberingType(
3004 SVX_NUM_CHARS_UPPER_LETTER_N);
3005 break;
3006 case RTF_PGNLCLTR:
3007 aNewSection.maNumType.SetNumberingType(
3008 SVX_NUM_CHARS_LOWER_LETTER_N);
3009 break;
3010 case RTF_SBKNONE:
3011 aNewSection.mnBkc = 0;
3012 break;
3013 case RTF_SBKCOL:
3014 aNewSection.mnBkc = 1;
3015 break;
3016 case RTF_PGBRDRT:
3017 SetBorderLine(aNewSection.maBox, BOX_LINE_TOP);
3018 break;
3020 case RTF_PGBRDRB:
3021 SetBorderLine(aNewSection.maBox, BOX_LINE_BOTTOM);
3022 break;
3024 case RTF_PGBRDRL:
3025 SetBorderLine(aNewSection.maBox, BOX_LINE_LEFT);
3026 break;
3028 case RTF_PGBRDRR:
3029 SetBorderLine(aNewSection.maBox, BOX_LINE_RIGHT);
3030 break;
3032 case RTF_PGBRDROPT:
3033 case RTF_ENDNHERE:
3034 case RTF_BINFSXN:
3035 case RTF_BINSXN:
3036 case RTF_SBKPAGE:
3037 case RTF_SBKEVEN:
3038 case RTF_SBKODD:
3039 case RTF_LINEBETCOL:
3040 case RTF_LINEMOD:
3041 case RTF_LINEX:
3042 case RTF_LINESTARTS:
3043 case RTF_LINERESTART:
3044 case RTF_LINEPAGE:
3045 case RTF_LINECONT:
3046 case RTF_GUTTERSXN:
3047 case RTF_PGNCONT:
3048 case RTF_PGNRESTART:
3049 case RTF_PGNX:
3050 case RTF_PGNY:
3051 case RTF_VERTALT:
3052 case RTF_VERTALB:
3053 case RTF_VERTALC:
3054 case RTF_VERTALJ:
3055 break;
3056 case RTF_TITLEPG:
3057 aNewSection.mbTitlepg = true;
3058 break;
3059 case RTF_HEADER:
3060 case RTF_HEADERL:
3061 case RTF_HEADERR:
3062 if (aNewSection.mpPageHdFt!=NULL)
3064 _pKeepHeader = NULL;
3065 bKeepFooter = true; // #i82008
3066 _pKeepFooter = &aNewSection.mpPageHdFt->GetMaster().GetFooter();
3068 case RTF_FOOTER:
3069 case RTF_FOOTERL:
3070 case RTF_FOOTERR:
3071 if (aNewSection.mpPageHdFt!=NULL && !bKeepFooter )
3073 _pKeepFooter = NULL;
3074 _pKeepHeader = &aNewSection.mpPageHdFt->GetMaster().GetHeader();
3076 bKeepFooter = false;
3077 if (!bNewSectionHeader) { //see #117914# topic 2). If a header is redefined in a section
3078 bNewSectionHeader=true; // a new header must be created.
3079 aNewSection.mpPageHdFt=NULL;
3081 if (!aNewSection.mpPageHdFt)
3083 String aName(RTL_CONSTASCII_STRINGPARAM("rtfHdFt"));
3084 aName += String::CreateFromInt32(maSegments.size());
3085 sal_uInt16 nPageNo = pDoc->MakePageDesc(aName);
3086 aNewSection.mpPageHdFt = &pDoc->_GetPageDesc(nPageNo);
3087 aNewSection.mbPageHdFtUsed = true;
3088 maSegments.maDummyPageNos.push_back(nPageNo);
3090 ReadHeaderFooter(nToken, aNewSection.mpPageHdFt);
3091 if (_pKeepHeader) aNewSection.mpPageHdFt->GetMaster().SetFmtAttr(*_pKeepHeader);
3092 if (_pKeepFooter) aNewSection.mpPageHdFt->GetMaster().SetFmtAttr(*_pKeepFooter);
3093 break;
3094 case RTF_FOOTERF:
3095 case RTF_HEADERF:
3096 if (!aNewSection.mpTitlePageHdFt)
3098 String aTitle(RTL_CONSTASCII_STRINGPARAM("rtfTitleHdFt"));
3099 aTitle += String::CreateFromInt32(maSegments.size());
3100 sal_uInt16 nPageNo = pDoc->MakePageDesc(aTitle);
3101 aNewSection.mpTitlePageHdFt = &pDoc->_GetPageDesc(nPageNo);
3102 aNewSection.mbTitlePageHdFtUsed = true;
3103 maSegments.maDummyPageNos.push_back(nPageNo);
3105 ReadHeaderFooter(nToken, aNewSection.mpTitlePageHdFt);
3106 break;
3107 case RTF_COLS:
3108 aNewSection.mnCols = nTokenValue;
3109 break;
3110 case RTF_COLSX:
3111 aNewSection.mnColsx = nTokenValue;
3112 break;
3113 case RTF_COLNO:
3115 // next token must be either colw or colsr
3116 unsigned long nAktCol = nValue;
3117 long nWidth = 0, nSpace = 0;
3118 int nColToken = GetNextToken();
3119 if (RTF_COLW == nColToken)
3121 // next token could be colsr (but not required)
3122 nWidth = nTokenValue;
3123 if( RTF_COLSR == GetNextToken() )
3124 nSpace = nTokenValue;
3125 else
3126 SkipToken( -1 ); // put back token
3128 else if (RTF_COLSR == nColToken)
3130 // next token must be colw (what sense should it make to have colsr only?!)
3131 nSpace = nTokenValue;
3132 if( RTF_COLW == GetNextToken() )
3133 nWidth = nTokenValue;
3134 else
3135 // what should we do if an isolated colsr without colw is found? Doesn't make sense!
3136 SkipToken( -1 ); // put back token
3138 else
3139 break;
3141 if (--nAktCol == (aNewSection.maColumns.size() / 2))
3143 aNewSection.maColumns.push_back(nWidth);
3144 aNewSection.maColumns.push_back(nSpace);
3147 break;
3148 case RTF_STEXTFLOW:
3149 aNewSection.mnStextflow = nTokenValue;
3150 break;
3151 case RTF_RTLSECT:
3152 aNewSection.mbRTLsection = true;
3153 break;
3154 case RTF_LTRSECT:
3155 aNewSection.mbRTLsection = false;
3156 break;
3157 case '{':
3159 short nSkip = 0;
3160 if( RTF_IGNOREFLAG != ( nToken = GetNextToken() ))
3161 nSkip = -1;
3162 else if( RTF_SECTFMT != (( nToken = GetNextToken() )
3163 & ~(0xff | RTF_SWGDEFS)) &&
3164 ( RTF_DOCFMT != ( nToken & ~(0xff | RTF_SWGDEFS))) )
3165 nSkip = -2;
3166 else
3168 // erstmal komplett ueberlesen
3169 SkipGroup();
3170 // ueberlese noch die schliessende Klammer
3171 GetNextToken();
3173 if (nSkip)
3175 bWeiter = ((-1 == nSkip) &&
3177 RTF_FOOTER == nToken || RTF_HEADER == nToken ||
3178 RTF_FOOTERR == nToken || RTF_HEADERR == nToken ||
3179 RTF_FOOTERL == nToken || RTF_HEADERL == nToken ||
3180 RTF_FOOTERF == nToken || RTF_HEADERF == nToken
3182 SkipToken (nSkip); // Ignore wieder zurueck
3185 break;
3186 case RTF_PAPERW:
3187 case RTF_PAPERH:
3188 case RTF_MARGL:
3189 case RTF_MARGR:
3190 case RTF_MARGT:
3191 case RTF_MARGB:
3192 case RTF_FACINGP:
3193 ASSERT(!this, "why are these tokens found in this section?");
3194 ReadDocControls( nToken );
3195 break;
3196 default:
3197 if (RTF_DOCFMT == (nToken & ~(0xff | RTF_SWGDEFS)))
3198 ReadDocControls( nToken );
3199 else if (RTF_SECTFMT == (nToken & ~(0xff | RTF_SWGDEFS)) ||
3200 RTF_UNKNOWNCONTROL == nToken)
3202 SvxRTFParser::NextToken(nToken);
3204 else
3205 bWeiter = false;
3206 break;
3209 if (bWeiter)
3210 nToken = GetNextToken();
3211 } while (bWeiter && IsParserWorking());
3213 if (bNewSection || maSegments.empty())
3215 AttrGroupEnd(); //#106493#
3216 if(!bContainsPara && !bContainsTablePara) //#117881#: bContainsTablePara is set in rtftbl.cxx
3217 pDoc->AppendTxtNode(*pPam->GetPoint());
3218 bContainsPara = false;
3219 bContainsTablePara = false;
3220 maSegments.push_back(rtfSection(*pPam->GetPoint(), aNewSection));
3222 else //modifying/replacing the current section
3224 SwPaM aPamStart(maSegments.back().maStart);
3225 maSegments.pop_back();
3226 maSegments.push_back(rtfSection(*aPamStart.GetPoint(), aNewSection));
3229 SkipToken(-1);
3232 void SwRTFParser::EnterEnvironment()
3237 void SwRTFParser::LeaveEnvironment()
3239 if(pRedlineDelete)
3241 delete pRedlineDelete;
3242 pRedlineDelete = 0;
3245 if(pRedlineInsert)
3247 delete pRedlineInsert;
3248 pRedlineInsert = 0;
3252 void SwRTFParser::SkipPageDescTbl()
3254 // M.M. #117907# I have to use this glorified SkipGroup because the
3255 // SvParser SkipGroup uses nNextCh which is not set correctly <groan>
3256 int nNumOpenBrakets = 1;
3258 while( nNumOpenBrakets && IsParserWorking() )
3260 switch( GetNextToken() )
3262 case '}':
3264 --nNumOpenBrakets;
3266 break;
3268 case '{':
3270 nNumOpenBrakets++;
3272 break;
3276 SkipToken( -1 );
3279 void SwRTFParser::ReadPageDescTbl()
3281 // dann erzeuge aus der SvxStyle-Tabelle die Swg-Collections, damit
3282 // diese auch in den Headers/Footer benutzt werden koennen!
3283 MakeStyleTab();
3284 // das default-Style schon gleich am ersten Node setzen
3285 SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 );
3286 if( !pColl )
3287 pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
3288 pDoc->SetTxtFmtColl( *pPam, pColl );
3290 int nToken, bSaveChkStyleAttr = IsChkStyleAttr();
3291 int nNumOpenBrakets = 1; // die erste wurde schon vorher erkannt !!
3293 SetChkStyleAttr(FALSE); // Attribute nicht gegen die Styles checken
3295 bInPgDscTbl = true;
3296 USHORT nPos = 0;
3297 SwPageDesc* pPg = 0;
3298 SwFrmFmt* pPgFmt = 0;
3300 SvxULSpaceItem aUL( RES_UL_SPACE ), aHUL( RES_UL_SPACE ), aFUL( RES_UL_SPACE );
3301 SvxLRSpaceItem aLR( RES_LR_SPACE ), aHLR( RES_LR_SPACE ), aFLR( RES_LR_SPACE );
3302 Size a4 = SvxPaperInfo::GetPaperSize(PAPER_A4);
3303 SwFmtFrmSize aSz( ATT_FIX_SIZE, a4.Width(), a4.Height() ); // DIN A4 defaulten
3304 SwFmtFrmSize aFSz( ATT_MIN_SIZE ), aHSz( ATT_MIN_SIZE );
3306 SvxFrameDirectionItem aFrmDir(FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR);
3308 USHORT nCols = USHRT_MAX, nColSpace = USHRT_MAX, nAktCol = 0;
3309 SvUShorts aColumns;
3311 while( nNumOpenBrakets && IsParserWorking() )
3313 switch( nToken = GetNextToken() )
3315 case '{':
3316 ++nNumOpenBrakets;
3317 break;
3318 case '}':
3319 if (1 == --nNumOpenBrakets)
3321 ASSERT(pPgFmt && pPg, "Serious problem here");
3322 if (pPgFmt && pPg)
3324 // PageDesc ist fertig, setze am Doc
3325 pPgFmt->SetFmtAttr(aFrmDir);
3326 pPgFmt->SetFmtAttr(aLR);
3327 pPgFmt->SetFmtAttr(aUL);
3328 pPgFmt->SetFmtAttr(aSz);
3329 ::lcl_SetFmtCol(*pPgFmt, nCols, nColSpace, aColumns);
3330 if (pPgFmt->GetHeader().GetHeaderFmt())
3332 SwFrmFmt* pHFmt =
3333 (SwFrmFmt*)pPgFmt->GetHeader().GetHeaderFmt();
3334 pHFmt->SetFmtAttr(aHUL);
3335 pHFmt->SetFmtAttr(aHLR);
3336 pHFmt->SetFmtAttr(aHSz);
3338 if (pPgFmt->GetFooter().GetFooterFmt())
3340 SwFrmFmt* pFFmt =
3341 (SwFrmFmt*)pPgFmt->GetFooter().GetFooterFmt();
3342 pFFmt->SetFmtAttr(aHUL);
3343 pFFmt->SetFmtAttr(aHLR);
3344 pFFmt->SetFmtAttr(aHSz);
3346 if( nPos < pDoc->GetPageDescCnt() )
3347 pDoc->ChgPageDesc(nPos++, *pPg);
3350 break;
3351 case RTF_PGDSC:
3352 if (nPos) // kein && wg MAC
3354 if (nPos != pDoc->MakePageDesc(
3355 String::CreateFromInt32(nTokenValue)))
3357 ASSERT( FALSE, "PageDesc an falscher Position" );
3360 pPg = &pDoc->_GetPageDesc(nPos);
3361 pPg->SetLandscape( FALSE );
3362 pPgFmt = &pPg->GetMaster();
3363 #ifndef CFRONT
3364 SETPAGEDESC_DEFAULTS:
3365 #endif
3366 aSz.SetWidth( a4.Width() ); aSz.SetHeight( a4.Height() );
3367 aLR.SetLeft( 0 ); aLR.SetRight( 0 );
3368 aUL.SetLower( 0 ); aUL.SetUpper( 0 );
3369 aHLR.SetLeft( 0 ); aHLR.SetRight( 0 );
3370 aHUL.SetLower( 0 ); aHUL.SetUpper( 0 );
3371 aFLR.SetLeft( 0 ); aFLR.SetRight( 0 );
3372 aFUL.SetLower( 0 ); aFUL.SetUpper( 0 );
3373 nCols = USHRT_MAX; nColSpace = USHRT_MAX; nAktCol = 0;
3374 aFSz.SetHeightSizeType( ATT_MIN_SIZE ); aFSz.SetHeight( 0 );
3375 aHSz.SetHeightSizeType( ATT_MIN_SIZE ); aHSz.SetHeight( 0 );
3376 break;
3378 case RTF_PGDSCUSE:
3379 pPg->WriteUseOn( (UseOnPage)nTokenValue );
3380 break;
3382 case RTF_PGDSCNXT:
3383 // setze erstmal nur die Nummer als Follow. Am Ende der
3384 // Tabelle wird diese entsprechend korrigiert !!
3385 if( nTokenValue )
3386 pPg->SetFollow( (const SwPageDesc*)nTokenValue );
3387 else
3388 pPg->SetFollow( & const_cast<const SwDoc *>(pDoc)
3389 ->GetPageDesc( 0 ) );
3390 break;
3392 case RTF_FORMULA: /* Zeichen "\|" !!! */
3393 pPgFmt->SetFmtAttr( aLR );
3394 pPgFmt->SetFmtAttr( aUL );
3395 pPgFmt->SetFmtAttr( aSz );
3396 ::lcl_SetFmtCol( *pPgFmt, nCols, nColSpace, aColumns );
3397 if( pPgFmt->GetHeader().GetHeaderFmt() )
3399 SwFrmFmt* pHFmt = (SwFrmFmt*)pPgFmt->GetHeader().GetHeaderFmt();
3400 pHFmt->SetFmtAttr( aHUL );
3401 pHFmt->SetFmtAttr( aHLR );
3402 pHFmt->SetFmtAttr( aHSz );
3404 if( pPgFmt->GetFooter().GetFooterFmt() )
3406 SwFrmFmt* pFFmt = (SwFrmFmt*)pPgFmt->GetFooter().GetFooterFmt();
3407 pFFmt->SetFmtAttr( aHUL );
3408 pFFmt->SetFmtAttr( aHLR );
3409 pFFmt->SetFmtAttr( aHSz );
3412 pPgFmt = &pPg->GetLeft();
3413 #ifndef CFRONT
3414 goto SETPAGEDESC_DEFAULTS;
3415 #else
3416 aLR.SetLeft( 0 ); aLR.SetRight( 0 );
3417 aUL.SetLower( 0 ); aUL.SetUpper( 0 );
3418 aHLR.SetLeft( 0 ); aHLR.SetRight( 0 );
3419 aHUL.SetLower( 0 ); aHUL.SetUpper( 0 );
3420 aFLR.SetLeft( 0 ); aFLR.SetRight( 0 );
3421 aFUL.SetLower( 0 ); aFUL.SetUpper( 0 );
3422 aSz.SetWidth( a4.Width() ); aSz.SetHeight( a4.Height() ); // DIN A4 default
3423 nCols = USHRT_MAX; nColSpace = USHRT_MAX; nAktCol = 0;
3424 aFSz.SetHeightSizeType( ATT_MIN_SIZE ); aFSz.SetHeight( 0 );
3425 aHSz.SetHeightSizeType( ATT_MIN_SIZE ); aHSz.SetHeight( 0 );
3426 break;
3427 #endif
3429 case RTF_RTLSECT:
3430 aFrmDir.SetValue(FRMDIR_HORI_RIGHT_TOP);
3431 break;
3433 case RTF_LTRSECT:
3434 aFrmDir.SetValue(FRMDIR_HORI_LEFT_TOP);
3435 break;
3437 // alt: LI/RI/SA/SB, neu: MARG?SXN
3438 case RTF_MARGLSXN:
3439 case RTF_LI: aLR.SetLeft( (USHORT)nTokenValue ); break;
3440 case RTF_MARGRSXN:
3441 case RTF_RI: aLR.SetRight( (USHORT)nTokenValue ); break;
3442 case RTF_MARGTSXN:
3443 case RTF_SA: aUL.SetUpper( (USHORT)nTokenValue ); break;
3444 case RTF_MARGBSXN:
3445 case RTF_SB: aUL.SetLower( (USHORT)nTokenValue ); break;
3446 case RTF_PGWSXN: aSz.SetWidth( nTokenValue ); break;
3447 case RTF_PGHSXN: aSz.SetHeight( nTokenValue ); break;
3449 case RTF_HEADERY: aHUL.SetUpper( (USHORT)nTokenValue ); break;
3450 case RTF_HEADER_YB: aHUL.SetLower( (USHORT)nTokenValue ); break;
3451 case RTF_HEADER_XL: aHLR.SetLeft( (USHORT)nTokenValue ); break;
3452 case RTF_HEADER_XR: aHLR.SetRight( (USHORT)nTokenValue ); break;
3453 case RTF_FOOTERY: aFUL.SetLower( (USHORT)nTokenValue ); break;
3454 case RTF_FOOTER_YT: aFUL.SetUpper( (USHORT)nTokenValue ); break;
3455 case RTF_FOOTER_XL: aFLR.SetLeft( (USHORT)nTokenValue ); break;
3456 case RTF_FOOTER_XR: aFLR.SetRight( (USHORT)nTokenValue ); break;
3458 case RTF_HEADER_YH:
3459 if( 0 > nTokenValue )
3461 aHSz.SetHeightSizeType( ATT_FIX_SIZE );
3462 nTokenValue = -nTokenValue;
3464 aHSz.SetHeight( (USHORT)nTokenValue );
3465 break;
3467 case RTF_FOOTER_YH:
3468 if( 0 > nTokenValue )
3470 aFSz.SetHeightSizeType( ATT_FIX_SIZE );
3471 nTokenValue = -nTokenValue;
3473 aFSz.SetHeight( (USHORT)nTokenValue );
3474 break;
3477 case RTF_LNDSCPSXN: pPg->SetLandscape( TRUE ); break;
3479 case RTF_COLS: nCols = (USHORT)nTokenValue; break;
3480 case RTF_COLSX: nColSpace = (USHORT)nTokenValue; break;
3482 case RTF_COLNO:
3483 nAktCol = (USHORT)nTokenValue;
3484 if( RTF_COLW == GetNextToken() )
3486 USHORT nWidth = USHORT( nTokenValue ), nSpace = 0;
3487 if( RTF_COLSR == GetNextToken() )
3488 nSpace = USHORT( nTokenValue );
3489 else
3490 SkipToken( -1 ); // wieder zurueck
3492 if( --nAktCol == ( aColumns.Count() / 2 ) )
3494 aColumns.Insert( nWidth, aColumns.Count() );
3495 aColumns.Insert( nSpace, aColumns.Count() );
3498 break;
3500 case RTF_PAGEBB:
3502 pPgFmt->SetFmtAttr( SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK ) );
3504 break;
3506 case RTF_HEADER:
3507 case RTF_HEADERL:
3508 case RTF_HEADERR:
3509 case RTF_FOOTER:
3510 case RTF_FOOTERL:
3511 case RTF_FOOTERR:
3512 case RTF_FOOTERF:
3513 case RTF_HEADERF:
3514 ReadHeaderFooter(nToken, pPg);
3515 --nNumOpenBrakets; // Klammer wird im ReadAttr ueberlesen!
3516 break;
3517 case RTF_TEXTTOKEN:
3518 if (!DelCharAtEnd(aToken, ';' ).Len())
3519 break;
3520 ASSERT(pPg, "Unexpected missing pPg");
3521 if (pPg)
3523 pPg->SetName(aToken);
3525 // sollte es eine Vorlage aus dem Pool sein ??
3526 USHORT n = SwStyleNameMapper::GetPoolIdFromUIName(aToken,
3527 nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC);
3528 if (USHRT_MAX != n)
3530 // dann setze bei der Neuen die entsp. PoolId
3531 pPg->SetPoolFmtId(n);
3534 break;
3535 case RTF_BRDBOX:
3536 if (3 == nNumOpenBrakets)
3538 ReadBorderAttr(SkipToken(-2),
3539 (SfxItemSet&)pPgFmt->GetAttrSet());
3540 --nNumOpenBrakets; // Klammer wird im ReadAttr ueberlesen!
3542 break;
3543 case RTF_SHADOW:
3544 if( 3 == nNumOpenBrakets )
3546 ReadAttr( SkipToken( -2 ), (SfxItemSet*)&pPgFmt->GetAttrSet() );
3547 --nNumOpenBrakets; // Klammer wird im ReadAttr ueberlesen!
3549 break;
3552 default:
3553 if( (nToken & ~0xff ) == RTF_SHADINGDEF )
3554 ReadBackgroundAttr( nToken, (SfxItemSet&)pPgFmt->GetAttrSet() );
3555 break;
3560 // setze jetzt noch bei allen die entsprechenden Follows !!
3561 // Die, die ueber die Tabelle eingelesen wurden und einen
3562 // Follow definiert haben, ist dieser als Tabposition im
3563 // Follow schon gesetzt.
3564 for( nPos = 0; nPos < pDoc->GetPageDescCnt(); ++nPos )
3566 SwPageDesc* pPgDsc = &pDoc->_GetPageDesc( nPos );
3567 if( (USHORT)(long)pPgDsc->GetFollow() < pDoc->GetPageDescCnt() )
3568 pPgDsc->SetFollow(& const_cast<const SwDoc *>(pDoc)
3569 ->GetPageDesc((USHORT)(long)
3570 pPgDsc->GetFollow()));
3573 SetChkStyleAttr( bSaveChkStyleAttr );
3575 bInPgDscTbl = false;
3576 nAktPageDesc = 0;
3577 nAktFirstPageDesc = 0;
3578 bSwPageDesc = true;
3579 SkipToken( -1 );
3582 // -------------- Methoden --------------------
3585 void SwRTFParser::ReadUnknownData()
3587 SvRTFParser::ReadUnknownData();
3590 void SwRTFParser::ReadOLEData()
3592 SvRTFParser::ReadOLEData();
3596 void SwRTFParser::ReadPrtData()
3598 while( IsParserWorking() )
3600 int nToken = GetNextToken();
3601 if( (RTF_TEXTTOKEN != nToken) && ('}' == nToken) )
3602 break;
3605 SkipToken( -1 ); // schliessende Klammer wieder zurueck!!
3608 static const SwNodeIndex* SetHeader(SwFrmFmt* pHdFtFmt, BOOL bReuseOld)
3610 ASSERT(pHdFtFmt, "Impossible, no header");
3611 const SwFrmFmt* pExisting = bReuseOld ?
3612 pHdFtFmt->GetHeader().GetHeaderFmt() : 0;
3613 if (!pExisting)
3615 //No existing header, create a new one
3616 pHdFtFmt->SetFmtAttr(SwFmtHeader(TRUE));
3617 pExisting = pHdFtFmt->GetHeader().GetHeaderFmt();
3619 return pExisting->GetCntnt().GetCntntIdx();
3622 static const SwNodeIndex* SetFooter(SwFrmFmt* pHdFtFmt, BOOL bReuseOld)
3624 ASSERT(pHdFtFmt, "Impossible, no footer");
3625 const SwFrmFmt* pExisting = bReuseOld ?
3626 pHdFtFmt->GetFooter().GetFooterFmt() : 0;
3627 if (!pExisting)
3629 //No exist footer, create a new one
3630 pHdFtFmt->SetFmtAttr(SwFmtFooter(TRUE));
3631 pExisting = pHdFtFmt->GetFooter().GetFooterFmt();
3633 return pExisting->GetCntnt().GetCntntIdx();
3637 void SwRTFParser::ReadHeaderFooter( int nToken, SwPageDesc* pPageDesc )
3639 ASSERT( RTF_FOOTNOTE == nToken ||
3640 RTF_FLY_INPARA == nToken ||
3641 pPageDesc, "PageDesc fehlt" );
3643 bool bContainsParaCache = bContainsPara;
3644 // alle wichtigen Sachen sichern
3645 SwPosition aSavePos( *pPam->GetPoint() );
3646 SvxRTFItemStack aSaveStack;
3647 aSaveStack.Insert( &GetAttrStack(), 0 );
3648 GetAttrStack().Remove( 0, GetAttrStack().Count() );
3650 // save the fly array - after read, all flys may be set into
3651 // the header/footer
3652 SwFlySaveArr aSaveArray( 255 < aFlyArr.Count() ? aFlyArr.Count() : 255 );
3653 aSaveArray.Insert( &aFlyArr, 0 );
3654 aFlyArr.Remove( 0, aFlyArr.Count() );
3655 BOOL bSetFlyInDoc = TRUE;
3657 const SwNodeIndex* pSttIdx = 0;
3658 SwFrmFmt* pHdFtFmt = 0;
3659 SwTxtAttr* pTxtAttr = 0;
3660 int bDelFirstChar = FALSE;
3661 bool bOldIsFootnote = mbIsFootnote;
3662 BOOL bOldGrpStt = sal::static_int_cast< BOOL, int >(IsNewGroup());
3664 int nNumOpenBrakets = GetOpenBrakets() - 1;
3666 switch( nToken )
3668 case RTF_FOOTNOTE:
3670 bool bIsEndNote = RTF_FTNALT == GetNextToken();
3671 if (!bIsEndNote)
3672 SkipToken(-1);
3674 SwTxtNode* pTxtNd = pPam->GetNode()->GetTxtNode();
3675 SwFmtFtn aFtnNote(bIsEndNote);
3676 xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex();
3678 if (nPos && !bFootnoteAutoNum)
3680 pPam->GetPoint()->nContent--;
3681 nPos--;
3682 aFtnNote.SetNumStr( pTxtNd->GetTxt().GetChar( nPos ) );
3683 ((String&)pTxtNd->GetTxt()).SetChar( nPos, CH_TXTATR_INWORD );
3684 bDelFirstChar = TRUE;
3687 pTxtAttr = pTxtNd->InsertItem( aFtnNote, nPos, nPos,
3688 bDelFirstChar ? nsSetAttrMode::SETATTR_NOTXTATRCHR : 0 );
3690 ASSERT( pTxtAttr, "konnte die Fussnote nicht einfuegen/finden" );
3692 if( pTxtAttr )
3693 pSttIdx = ((SwTxtFtn*)pTxtAttr)->GetStartNode();
3694 mbIsFootnote = true;
3696 // wurde an der Position ein Escapement aufgespannt, so entferne
3697 // das jetzt. Fussnoten sind bei uns immer hochgestellt.
3698 SvxRTFItemStackTypePtr pTmp = aSaveStack.Top();
3699 if( pTmp && pTmp->GetSttNodeIdx() ==
3700 pPam->GetPoint()->nNode.GetIndex() &&
3701 pTmp->GetSttCnt() == nPos )
3702 pTmp->GetAttrSet().ClearItem( RES_CHRATR_ESCAPEMENT );
3704 break;
3706 case RTF_FLY_INPARA:
3708 xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex();
3709 SfxItemSet aSet( pDoc->GetAttrPool(), RES_FRMATR_BEGIN,
3710 RES_FRMATR_END-1 );
3711 aSet.Put( SwFmtAnchor( FLY_IN_CNTNT ));
3712 pHdFtFmt = pDoc->MakeFlySection( FLY_IN_CNTNT, pPam->GetPoint(), &aSet );
3714 pTxtAttr = pPam->GetNode()->GetTxtNode()->GetTxtAttr(
3715 nPos, RES_TXTATR_FLYCNT );
3716 ASSERT( pTxtAttr, "konnte den Fly nicht einfuegen/finden" );
3718 pSttIdx = pHdFtFmt->GetCntnt().GetCntntIdx();
3719 bSetFlyInDoc = FALSE;
3721 break;
3723 case RTF_HEADERF:
3724 case RTF_HEADER:
3725 pPageDesc->WriteUseOn( (UseOnPage)(pPageDesc->ReadUseOn() | nsUseOnPage::PD_HEADERSHARE) );
3726 pHdFtFmt = &pPageDesc->GetMaster();
3727 pSttIdx = SetHeader( pHdFtFmt, FALSE );
3728 break;
3730 case RTF_HEADERL:
3731 // we cannot have left or right, must have always both
3732 pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_HEADERSHARE) | nsUseOnPage::PD_ALL));
3733 SetHeader( pPageDesc->GetRightFmt(), TRUE );
3734 pHdFtFmt = pPageDesc->GetLeftFmt();
3735 pSttIdx = SetHeader(pHdFtFmt, FALSE );
3736 break;
3738 case RTF_HEADERR:
3739 // we cannot have left or right, must have always both
3740 pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_HEADERSHARE) | nsUseOnPage::PD_ALL));
3741 SetHeader( pPageDesc->GetLeftFmt(), TRUE );
3742 pHdFtFmt = pPageDesc->GetRightFmt();
3743 pSttIdx = SetHeader(pHdFtFmt, FALSE );
3744 break;
3746 case RTF_FOOTERF:
3747 case RTF_FOOTER:
3748 pPageDesc->WriteUseOn( (UseOnPage)(pPageDesc->ReadUseOn() | nsUseOnPage::PD_FOOTERSHARE) );
3749 pHdFtFmt = &pPageDesc->GetMaster();
3750 pSttIdx = SetFooter(pHdFtFmt, FALSE );
3751 break;
3753 case RTF_FOOTERL:
3754 // we cannot have left or right, must have always both
3755 pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_FOOTERSHARE) | nsUseOnPage::PD_ALL));
3756 SetFooter( pPageDesc->GetRightFmt(), TRUE );
3757 pHdFtFmt = pPageDesc->GetLeftFmt();
3758 pSttIdx = SetFooter(pHdFtFmt, FALSE );
3759 break;
3761 case RTF_FOOTERR:
3762 // we cannot have left or right, must have always both
3763 pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_FOOTERSHARE) | nsUseOnPage::PD_ALL));
3764 SetFooter( pPageDesc->GetLeftFmt(), TRUE );
3765 pHdFtFmt = pPageDesc->GetRightFmt();
3766 pSttIdx = SetFooter(pHdFtFmt, FALSE );
3767 break;
3770 USHORT nOldFlyArrCnt = aFlyArr.Count();
3771 if( !pSttIdx )
3772 SkipGroup();
3773 else
3775 // es ist auf jedenfall jetzt ein TextNode im Kopf/Fusszeilen-Bereich
3776 // vorhanden. Dieser muss jetzt nur noch gefunden und der neue Cursor
3777 // dort hinein gesetzt werden.
3778 SwCntntNode *pNode = pDoc->GetNodes()[ pSttIdx->GetIndex()+1 ]->
3779 GetCntntNode();
3781 // immer ans Ende der Section einfuegen !!
3782 pPam->GetPoint()->nNode = *pNode->EndOfSectionNode();
3783 pPam->Move( fnMoveBackward );
3785 SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 );
3786 if( !pColl )
3787 pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
3788 pDoc->SetTxtFmtColl( *pPam, pColl );
3790 SetNewGroup( TRUE );
3792 while( !( nNumOpenBrakets == GetOpenBrakets() && !GetStackPos()) && IsParserWorking() )
3794 switch( nToken = GetNextToken() )
3796 case RTF_U:
3797 if( bDelFirstChar )
3799 bDelFirstChar = FALSE;
3800 nToken = 0;
3802 break;
3804 case RTF_TEXTTOKEN:
3805 if( bDelFirstChar )
3807 if( !aToken.Erase( 0, 1 ).Len() )
3808 nToken = 0;
3809 bDelFirstChar = FALSE;
3811 break;
3813 if( nToken )
3814 NextToken( nToken );
3817 SetAllAttrOfStk();
3818 if( aFlyArr.Count() && bSetFlyInDoc )
3819 SetFlysInDoc();
3821 // sollte der letze Node leer sein, dann loesche ihn
3822 // (\par heisst ja Absatzende und nicht neuer Absatz!)
3823 DelLastNode();
3826 // vom FlyFmt noch die richtigen Attribute setzen
3827 if( pTxtAttr && RES_TXTATR_FLYCNT == pTxtAttr->Which() )
3829 // is add a new fly ?
3830 if( nOldFlyArrCnt < aFlyArr.Count() )
3832 SwFlySave* pFlySave = aFlyArr[ aFlyArr.Count()-1 ];
3833 pFlySave->aFlySet.ClearItem( RES_ANCHOR );
3834 pHdFtFmt->SetFmtAttr( pFlySave->aFlySet );
3835 aFlyArr.DeleteAndDestroy( aFlyArr.Count() - 1 );
3837 else
3839 // no, so remove the created textattribute
3840 SwFrmFmt* pFlyFmt = pTxtAttr->GetFlyCnt().GetFrmFmt();
3841 // remove the pam from the flynode
3842 *pPam->GetPoint() = aSavePos;
3843 pDoc->DelLayoutFmt( pFlyFmt );
3847 bFootnoteAutoNum = FALSE; // default auf aus!
3849 // und alles wieder zurueck
3850 *pPam->GetPoint() = aSavePos;
3851 if (mbIsFootnote)
3852 SetNewGroup( bOldGrpStt ); // Status wieder zurueck
3853 else
3854 SetNewGroup( FALSE ); // { - Klammer war kein Group-Start!
3855 mbIsFootnote = bOldIsFootnote;
3856 GetAttrStack().Insert( &aSaveStack, 0 );
3858 aFlyArr.Insert( &aSaveArray, 0 );
3859 aSaveArray.Remove( 0, aSaveArray.Count() );
3860 bContainsPara = bContainsParaCache;
3863 void SwRTFParser::SetSwgValues( SfxItemSet& rSet )
3865 const SfxPoolItem* pItem;
3866 // Escapement korrigieren
3867 if( SFX_ITEM_SET == rSet.GetItemState( RES_CHRATR_ESCAPEMENT, FALSE, &pItem ))
3869 /* prozentuale Veraenderung errechnen !
3870 * Formel : (FontSize * 1/20 ) pts Escapement * 2
3871 * ----------------------- = ----------------
3872 * 100% x
3875 // die richtige
3876 long nEsc = ((SvxEscapementItem*)pItem)->GetEsc();
3878 // automatische Ausrichtung wurde schon richtig berechnet
3879 if( DFLT_ESC_AUTO_SUPER != nEsc && DFLT_ESC_AUTO_SUB != nEsc )
3881 const SvxFontHeightItem& rFH = GetSize( rSet );
3882 nEsc *= 1000L;
3883 if(rFH.GetHeight()) nEsc /= long(rFH.GetHeight()); // #i77256#
3885 SvxEscapementItem aEsc( (short) nEsc,
3886 ((SvxEscapementItem*)pItem)->GetProp(), RES_CHRATR_ESCAPEMENT);
3887 rSet.Put( aEsc );
3891 // TabStops anpassen
3892 if( SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_TABSTOP, FALSE, &pItem ))
3894 const SvxLRSpaceItem& rLR = GetLRSpace( rSet );
3895 SvxTabStopItem aTStop( *(SvxTabStopItem*)pItem );
3897 long nOffset = rLR.GetTxtLeft();
3898 if( nOffset )
3900 // Tabs anpassen !!
3901 SvxTabStop* pTabs = (SvxTabStop*)aTStop.GetStart();
3902 for( USHORT n = aTStop.Count(); n; --n, ++pTabs)
3903 if( SVX_TAB_ADJUST_DEFAULT != pTabs->GetAdjustment() )
3904 pTabs->GetTabPos() -= nOffset;
3906 // negativer Einzug, dann auf 0 Pos einen Tab setzen
3907 if( rLR.GetTxtFirstLineOfst() < 0 )
3908 aTStop.Insert( SvxTabStop() );
3911 if( !aTStop.Count() )
3913 const SvxTabStopItem& rDflt = (const SvxTabStopItem&)rSet.
3914 GetPool()->GetDefaultItem(RES_PARATR_TABSTOP);
3915 if( rDflt.Count() )
3916 aTStop.Insert( &rDflt, 0 );
3918 rSet.Put( aTStop );
3920 else if( SFX_ITEM_SET == rSet.GetItemState( RES_LR_SPACE, FALSE, &pItem )
3921 && ((SvxLRSpaceItem*)pItem)->GetTxtFirstLineOfst() < 0 )
3923 // negativer Einzug, dann auf 0 Pos einen Tab setzen
3924 rSet.Put( SvxTabStopItem( 1, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP ));
3927 // NumRules anpassen
3928 if( !bStyleTabValid &&
3929 SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_NUMRULE, FALSE, &pItem ))
3931 // dann steht im Namen nur ein Verweis in das ListArray
3932 SwNumRule* pRule = GetNumRuleOfListNo( ((SwNumRuleItem*)pItem)->
3933 GetValue().ToInt32() );
3934 if( pRule )
3935 rSet.Put( SwNumRuleItem( pRule->GetName() ));
3936 else
3937 rSet.ClearItem( RES_PARATR_NUMRULE );
3943 ????????????????????????????????????????????????????????????????????
3944 ?? muss die LineSpacing Hoehe 200Twip betragen ??
3945 ?? in rtfitem.hxx wird es auf 0 defaultet. Wenn ja, dann muss hier
3946 ?? ein neues Item gesetzt werden!!!!
3947 ????????????????????????????????????????????????????????????????????
3949 // LineSpacing korrigieren
3950 if( SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_LINESPACING, FALSE, &pItem ))
3952 const SvxLineSpacingItem* pLS = (const SvxLineSpacingItem*)pItem;
3953 SvxLineSpacingItem aNew;
3955 aNew.SetInterLineSpace( pLS->GetInterLineSpace() );
3956 aNew.GetLineSpaceRule() = pLS->GetLineSpaceRule();
3957 aNew.SetPropLineSpace( pLS->GetPropLineSpace() );
3958 aNew.GetInterLineSpaceRule() = pLS->GetInterLineSpaceRule();
3960 rSet.Put( aNew );
3962 ?????????????????????????????????????????????????????????????????? */
3967 SwTxtFmtColl* SwRTFParser::MakeColl(const String& rName, USHORT nPos,
3968 BYTE nOutlineLevel, bool& rbCollExist)
3970 if( BYTE(-1) == nOutlineLevel )
3971 //nOutlineLevel = NO_NUMBERING;
3972 nOutlineLevel = MAXLEVEL;//#outline level,zhaojianwei
3974 rbCollExist = false;
3975 SwTxtFmtColl* pColl;
3976 String aNm( rName );
3977 if( !aNm.Len() )
3979 ASSERT(!this, "not a bug, but I (cmc) want to see an example of this");
3980 if( !nPos )
3982 pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
3983 //pColl->SetOutlineLevel( nOutlineLevel ); //#outline level,removed by zhaojianwei
3984 if(nOutlineLevel < MAXLEVEL ) //->add by zhaojianwei
3985 pColl->AssignToListLevelOfOutlineStyle( nOutlineLevel );
3986 else
3987 pColl->DeleteAssignmentToListLevelOfOutlineStyle(); //<-end,zhaojianwei
3988 return pColl;
3991 // erzeuge einen Namen
3992 aNm.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NoName(" ));
3993 aNm += String::CreateFromInt32( nPos );
3994 aNm += ')';
3996 ww::sti eSti = ww::GetCanonicalStiFromEnglishName(rName);
3997 sw::util::ParaStyleMapper::StyleResult aResult =
3998 maParaStyleMapper.GetStyle(rName, eSti);
3999 pColl = aResult.first;
4000 rbCollExist = aResult.second;
4001 if (IsNewDoc() && rbCollExist)
4003 // --> OD 2007-01-25 #i73790# - method renamed
4004 pColl->ResetAllFmtAttr();
4005 // <--
4006 rbCollExist = false;
4009 if (!rbCollExist)
4011 //pColl->SetOutlineLevel( nOutlineLevel ); //#outline level,removed by zhaojianwei
4012 if(nOutlineLevel < MAXLEVEL) //->add by zhaojianwei
4013 pColl->AssignToListLevelOfOutlineStyle( nOutlineLevel );
4014 else
4015 pColl->DeleteAssignmentToListLevelOfOutlineStyle(); //<-end,zhaojianwei
4018 return pColl;
4021 SwCharFmt* SwRTFParser::MakeCharFmt(const String& rName, USHORT nPos,
4022 int& rbCollExist)
4024 rbCollExist = FALSE;
4025 SwCharFmt* pFmt;
4026 String aNm( rName );
4027 if( !aNm.Len() )
4029 ASSERT(!this, "not a bug, but I (cmc) want to see an example of this");
4030 aNm.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NoName(" ));
4031 aNm += String::CreateFromInt32( nPos );
4032 aNm += ')';
4035 ww::sti eSti = ww::GetCanonicalStiFromEnglishName(rName);
4036 sw::util::CharStyleMapper::StyleResult aResult =
4037 maCharStyleMapper.GetStyle(rName, eSti);
4038 pFmt = aResult.first;
4039 rbCollExist = aResult.second;
4040 if (IsNewDoc() && rbCollExist)
4042 // --> OD 2007-01-25 #i73790# - method renamed
4043 pFmt->ResetAllFmtAttr();
4044 // <--
4045 rbCollExist = false;
4047 return pFmt;
4050 void SwRTFParser::SetStyleAttr( SfxItemSet& rCollSet,
4051 const SfxItemSet& rStyleSet,
4052 const SfxItemSet& rDerivedSet )
4054 rCollSet.Put( rStyleSet );
4055 if( rDerivedSet.Count() )
4057 // suche alle Attribute, die neu gesetzt werden:
4058 const SfxPoolItem* pItem;
4059 SfxItemIter aIter( rDerivedSet );
4060 USHORT nWhich = aIter.GetCurItem()->Which();
4061 while( TRUE )
4063 switch( rStyleSet.GetItemState( nWhich, FALSE, &pItem ) )
4065 case SFX_ITEM_DEFAULT:
4066 // auf default zuruecksetzen
4067 if( RES_FRMATR_END > nWhich )
4068 rCollSet.Put( rCollSet.GetPool()->GetDefaultItem( nWhich ));
4069 break;
4070 case SFX_ITEM_SET:
4071 if( *pItem == *aIter.GetCurItem() ) // gleiches Attribut?
4072 // definition kommt aus dem Parent
4073 rCollSet.ClearItem( nWhich ); // loeschen
4074 break;
4077 if( aIter.IsAtEnd() )
4078 break;
4079 nWhich = aIter.NextItem()->Which();
4082 // und jetzt noch auf unsere Werte abgleichen
4083 SetSwgValues( rCollSet );
4086 SwTxtFmtColl* SwRTFParser::MakeStyle( USHORT nNo, const SvxRTFStyleType& rStyle)
4088 bool bCollExist;
4089 SwTxtFmtColl* pColl = MakeColl( rStyle.sName, USHORT(nNo),
4090 rStyle.nOutlineNo, bCollExist);
4091 aTxtCollTbl.Insert( nNo, pColl );
4093 // in bestehendes Dok einfuegen, dann keine Ableitung usw. setzen
4094 if( bCollExist )
4095 return pColl;
4097 USHORT nStyleNo = rStyle.nBasedOn;
4098 if( rStyle.bBasedOnIsSet && nStyleNo != nNo )
4100 SvxRTFStyleType* pDerivedStyle = GetStyleTbl().Get( nStyleNo );
4101 SwTxtFmtColl* pDerivedColl = aTxtCollTbl.Get( nStyleNo );
4102 if( !pDerivedColl ) // noch nicht vorhanden, also anlegen
4104 // ist die ueberhaupt als Style vorhanden ?
4105 pDerivedColl = pDerivedStyle
4106 ? MakeStyle( nStyleNo, *pDerivedStyle )
4107 : pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
4110 if( pColl == pDerivedColl )
4111 ((SfxItemSet&)pColl->GetAttrSet()).Put( rStyle.aAttrSet );
4112 else
4114 pColl->SetDerivedFrom( pDerivedColl );
4116 // setze die richtigen Attribute
4117 const SfxItemSet* pDerivedSet;
4118 if( pDerivedStyle )
4119 pDerivedSet = &pDerivedStyle->aAttrSet;
4120 else
4121 pDerivedSet = &pDerivedColl->GetAttrSet();
4123 SetStyleAttr( (SfxItemSet&)pColl->GetAttrSet(),
4124 rStyle.aAttrSet, *pDerivedSet );
4127 else
4128 ((SfxItemSet&)pColl->GetAttrSet()).Put( rStyle.aAttrSet );
4131 nStyleNo = rStyle.nNext;
4132 if( nStyleNo != nNo )
4134 SwTxtFmtColl* pNext = aTxtCollTbl.Get( nStyleNo );
4135 if( !pNext ) // noch nicht vorhanden, also anlegen
4137 // ist die ueberhaupt als Style vorhanden ?
4138 SvxRTFStyleType* pMkStyle = GetStyleTbl().Get( nStyleNo );
4139 pNext = pMkStyle
4140 ? MakeStyle( nStyleNo, *pMkStyle )
4141 : pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
4143 pColl->SetNextTxtFmtColl( *pNext );
4145 return pColl;
4148 SwCharFmt* SwRTFParser::MakeCharStyle( USHORT nNo, const SvxRTFStyleType& rStyle )
4150 int bCollExist;
4151 SwCharFmt* pFmt = MakeCharFmt( rStyle.sName, USHORT(nNo), bCollExist );
4152 aCharFmtTbl.Insert( nNo, pFmt );
4154 // in bestehendes Dok einfuegen, dann keine Ableitung usw. setzen
4155 if( bCollExist )
4156 return pFmt;
4158 USHORT nStyleNo = rStyle.nBasedOn;
4159 if( rStyle.bBasedOnIsSet && nStyleNo != nNo )
4161 SvxRTFStyleType* pDerivedStyle = GetStyleTbl().Get( nStyleNo );
4162 SwCharFmt* pDerivedFmt = aCharFmtTbl.Get( nStyleNo );
4163 if( !pDerivedFmt ) // noch nicht vorhanden, also anlegen
4165 // ist die ueberhaupt als Style vorhanden ?
4166 pDerivedFmt = pDerivedStyle
4167 ? MakeCharStyle( nStyleNo, *pDerivedStyle )
4168 : pDoc->GetDfltCharFmt();
4171 if( pFmt == pDerivedFmt )
4172 ((SfxItemSet&)pFmt->GetAttrSet()).Put( rStyle.aAttrSet );
4173 else
4175 pFmt->SetDerivedFrom( pDerivedFmt );
4177 // setze die richtigen Attribute
4178 const SfxItemSet* pDerivedSet;
4179 if( pDerivedStyle )
4180 pDerivedSet = &pDerivedStyle->aAttrSet;
4181 else
4182 pDerivedSet = &pDerivedFmt->GetAttrSet();
4184 SetStyleAttr( (SfxItemSet&)pFmt->GetAttrSet(),
4185 rStyle.aAttrSet, *pDerivedSet );
4188 else
4189 ((SfxItemSet&)pFmt->GetAttrSet()).Put( rStyle.aAttrSet );
4191 return pFmt;
4194 // loesche den letzten Node (Tabelle/Fly/Ftn/..)
4195 void SwRTFParser::DelLastNode()
4197 // sollte der letze Node leer sein, dann loesche ihn
4198 // (\par heisst ja Absatzende und nicht neuer Absatz!)
4200 if( !pPam->GetPoint()->nContent.GetIndex() )
4202 ULONG nNodeIdx = pPam->GetPoint()->nNode.GetIndex();
4203 SwCntntNode* pCNd = pDoc->GetNodes()[ nNodeIdx ]->GetCntntNode();
4204 // paragraphs with page break information are not empty! see #117914# topic 1)
4205 if(const SfxPoolItem* pItem=&(pCNd->GetAttr( RES_PAGEDESC, FALSE)))
4207 SwFmtPageDesc* pPageDescItem = ((SwFmtPageDesc*)pItem);
4208 if (pPageDescItem->GetPageDesc()!=NULL)
4209 return;
4212 if( pCNd && pCNd->StartOfSectionIndex()+2 <
4213 pCNd->EndOfSectionIndex() )
4215 if( GetAttrStack().Count() )
4217 // Attribut Stack-Eintraege, muessen ans Ende des vorherigen
4218 // Nodes verschoben werden.
4219 BOOL bMove = FALSE;
4220 for( USHORT n = GetAttrStack().Count(); n; )
4222 SvxRTFItemStackType* pStkEntry = (SvxRTFItemStackType*)
4223 GetAttrStack()[ --n ];
4224 if( nNodeIdx == pStkEntry->GetSttNode().GetIdx() )
4226 if( !bMove )
4228 pPam->Move( fnMoveBackward );
4229 bMove = TRUE;
4231 pStkEntry->SetStartPos( SwxPosition( pPam ) );
4234 if( bMove )
4235 pPam->Move( fnMoveForward );
4237 pPam->GetPoint()->nContent.Assign( 0, 0 );
4238 pPam->SetMark();
4239 pPam->DeleteMark();
4241 pDoc->GetNodes().Delete( pPam->GetPoint()->nNode );
4246 // fuer Tokens, die im ReadAttr nicht ausgewertet werden
4247 void SwRTFParser::UnknownAttrToken( int nToken, SfxItemSet* pSet )
4249 switch( nToken )
4251 case RTF_INTBL:
4253 if( !pTableNode ) // Tabelle nicht mehr vorhanden ?
4254 NewTblLine(); // evt. Line copieren
4255 else
4257 static int _do=0; //$flr See #117881# for explanation.
4258 // Crsr nicht mehr in der Tabelle ?
4259 if( !pPam->GetNode()->FindTableNode() && _do )
4261 ULONG nOldPos = pPam->GetPoint()->nNode.GetIndex();
4263 // dann wieder in die letzte Box setzen
4264 // (kann durch einlesen von Flys geschehen!)
4265 pPam->GetPoint()->nNode = *pTableNode->EndOfSectionNode();
4266 pPam->Move( fnMoveBackward );
4268 // alle Attribute, die schon auf den nachfolgen zeigen
4269 // auf die neue Box umsetzen !!
4270 SvxRTFItemStack& rAttrStk = GetAttrStack();
4271 const SvxRTFItemStackType* pStk;
4272 for( USHORT n = 0; n < rAttrStk.Count(); ++n )
4273 if( ( pStk = rAttrStk[ n ])->GetSttNodeIdx() == nOldPos &&
4274 !pStk->GetSttCnt() )
4275 ((SvxRTFItemStackType*)pStk)->SetStartPos( SwxPosition( pPam ) );
4279 break;
4281 case RTF_PAGEBB:
4283 pSet->Put( SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK ));
4285 break;
4287 case RTF_PGBRK:
4289 pSet->Put( SvxFmtBreakItem( 1 == nTokenValue ?
4290 SVX_BREAK_PAGE_BOTH : SVX_BREAK_PAGE_AFTER, RES_BREAK ));
4292 break;
4294 case RTF_PGDSCNO:
4295 if( IsNewDoc() && bSwPageDesc &&
4296 USHORT(nTokenValue) < pDoc->GetPageDescCnt() )
4298 const SwPageDesc* pPgDsc = &const_cast<const SwDoc *>(pDoc)
4299 ->GetPageDesc( (USHORT)nTokenValue );
4300 pDoc->Insert( *pPam, SwFmtPageDesc( pPgDsc ), 0);
4302 break;
4303 case RTF_CS:
4305 SwCharFmt* pFmt = aCharFmtTbl.Get( nTokenValue );
4306 if( pFmt )
4307 pSet->Put( SwFmtCharFmt( pFmt ));
4309 break;
4311 case RTF_LS:
4312 if( -1 != nTokenValue )
4314 if( bStyleTabValid )
4316 // dann ist auch die ListTabelle gueltig, also suche die
4317 // enstprechende NumRule
4318 SwNumRule* pRule = GetNumRuleOfListNo( nTokenValue );
4319 if( pRule )
4320 pSet->Put( SwNumRuleItem( pRule->GetName() ));
4322 if( SFX_ITEM_SET != pSet->GetItemState( FN_PARAM_NUM_LEVEL, FALSE ))
4323 pSet->Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 ));
4325 else
4327 // wir sind in der Style-Definitions - Phase. Der Name
4328 // wird dann spaeter umgesetzt
4329 //#117891# pSet->Put( SwNumRuleItem( String::CreateFromInt32( nTokenValue )));
4333 break;
4335 case RTF_ILVL:
4336 case RTF_SOUTLVL:
4338 BYTE nLevel = MAXLEVEL <= nTokenValue ? MAXLEVEL - 1
4339 : BYTE( nTokenValue );
4340 pSet->Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, nLevel ));
4342 break;
4345 case RTF_SBYS:
4346 case RTF_EXPND:
4347 case RTF_KEEP:
4348 case RTF_KEEPN:
4354 void SwRTFParser::ReadInfo( const sal_Char* pChkForVerNo )
4356 sal_Char __READONLY_DATA aChkForVerNo[] = "StarWriter";
4358 // falls nicht schon was vorgegeben wurde, setzen wir unseren Namen
4359 // rein. Wenn das im Kommentar match, wird im Parser die VersionNummer
4360 // gelesen und gesetzt
4361 if( !pChkForVerNo )
4362 pChkForVerNo = aChkForVerNo;
4364 SvxRTFParser::ReadInfo( pChkForVerNo );
4367 void SwRTFParser::ReadUserProperties()
4369 // For now we don't support user properties but at least the parser is here.
4370 // At the moment it just swallows the tokens to prevent them being displayed
4371 int nNumOpenBrakets = 1, nToken;
4373 while( nNumOpenBrakets && IsParserWorking() )
4375 switch( nToken = GetNextToken() )
4377 case '}':
4378 --nNumOpenBrakets;
4379 break;
4380 case '{':
4382 if( RTF_IGNOREFLAG != GetNextToken() )
4383 nToken = SkipToken( -1 );
4384 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
4385 nToken = SkipToken( -2 );
4386 else
4388 // gleich herausfiltern
4389 ReadUnknownData();
4390 nToken = GetNextToken();
4391 if( '}' != nToken )
4392 eState = SVPAR_ERROR;
4393 break;
4395 ++nNumOpenBrakets;
4397 break;
4399 case RTF_PROPNAME:
4400 SkipGroup();
4401 break;
4403 case RTF_PROPTYPE:
4404 break;
4406 case RTF_STATICVAL:
4407 SkipGroup();
4408 break;
4410 // default:
4414 SkipToken( -1 );
4418 #ifdef USED
4419 void SwRTFParser::SaveState( int nToken )
4421 SvxRTFParser::SaveState( nToken );
4424 void SwRTFParser::RestoreState()
4426 SvxRTFParser::RestoreState();
4428 #endif
4430 /*\f*/
4432 BookmarkPosition::BookmarkPosition(const SwPaM &rPaM)
4433 : maMkNode(rPaM.GetMark()->nNode),
4434 mnMkCntnt(rPaM.GetMark()->nContent.GetIndex())
4438 BookmarkPosition::BookmarkPosition(const BookmarkPosition &rEntry)
4439 : maMkNode(rEntry.maMkNode), mnMkCntnt(rEntry.mnMkCntnt)
4443 bool BookmarkPosition::operator==(const BookmarkPosition rhs)
4445 return(maMkNode.GetIndex() == rhs.maMkNode.GetIndex() && mnMkCntnt == rhs.mnMkCntnt);
4448 ULONG SwNodeIdx::GetIdx() const
4450 return aIdx.GetIndex();
4453 SvxNodeIdx* SwNodeIdx::Clone() const
4455 return new SwNodeIdx( aIdx );
4458 SvxPosition* SwxPosition::Clone() const
4460 return new SwxPosition( pPam );
4463 SvxNodeIdx* SwxPosition::MakeNodeIdx() const
4465 return new SwNodeIdx( pPam->GetPoint()->nNode );
4468 ULONG SwxPosition::GetNodeIdx() const
4470 return pPam->GetPoint()->nNode.GetIndex();
4473 xub_StrLen SwxPosition::GetCntIdx() const
4475 return pPam->GetPoint()->nContent.GetIndex();
4478 /* vi:set tabstop=4 shiftwidth=4 expandtab: */