1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_sw.hxx"
24
25 #include <hintids.hxx>
26 #include <stack>
27 #include <tools/errinf.hxx>
28 #include <tools/stream.hxx>
29 #include <svl/itemiter.hxx>
30 #include <svtools/rtftoken.h>
31 #include <svl/intitem.hxx>
32 #include <editeng/fhgtitem.hxx>
33 #include <editeng/ulspitem.hxx>
34 #include <editeng/tstpitem.hxx>
35 #include <editeng/lspcitem.hxx>
36 #include <editeng/lrspitem.hxx>
37 #include <editeng/escpitem.hxx>
38 #include <editeng/fontitem.hxx>
39 #include <editeng/frmdiritem.hxx>
40 #include <editeng/hyznitem.hxx>
41 #include <fmtpdsc.hxx>
42 #include <fmtfld.hxx>
43 #include <fmthdft.hxx>
44 #include <fmtcntnt.hxx>
45 #include <txtftn.hxx>
46 #include <fmtclds.hxx>
47 #include <fmtftn.hxx>
48 #include <fmtfsize.hxx>
49 #include <fmtflcnt.hxx>
50 #include <fmtanchr.hxx>
51 #include <frmatr.hxx>
52 #include <docstat.hxx>
53 #include <swtable.hxx>
54 #include <shellio.hxx>
55 #include <swtypes.hxx>
56 #include <ndtxt.hxx>
57 #include <doc.hxx>
58 #include <docary.hxx>
59 #include <pam.hxx>
60 #include <mdiexp.hxx> // ...Percent()
61 #include <swparrtf.hxx>
62 #include <charfmt.hxx>
63 #include <pagedesc.hxx>
64 #include <ftninfo.hxx>
65 #include <docufld.hxx>
66 #include <flddat.hxx>
67 #include <fltini.hxx>
68 #include <fchrfmt.hxx>
69 #include <paratr.hxx>
70 #include <section.hxx>
71 #include <fmtclbl.hxx>
72 #include <viewsh.hxx>
73 #include <shellres.hxx>
74 #include <hfspacingitem.hxx>
75 #include <tox.hxx>
76 #include <swerror.h>
77 #include <cmdid.h>
78 #include <statstr.hrc> // ResId fuer Statusleiste
79 #include <SwStyleNameMapper.hxx>
80 #include <tblsel.hxx> // SwSelBoxes
81 #include <docsh.hxx>
82 #include <fmtlsplt.hxx> // SwLayoutSplit
83 #include <editeng/keepitem.hxx>
84 #include <svx/svdopath.hxx>
85 #include <svx/svdorect.hxx>
86 #include <fmtsrnd.hxx>
87 #include <fmtfollowtextflow.hxx>
88 #include <svx/svdmodel.hxx>
89 #include <svx/svdpage.hxx>
90 #include <editeng/opaqitem.hxx>
91 #include "svx/svdograf.hxx"
92 #include <svx/xflclit.hxx>
93 #include <svx/xlnwtit.hxx>
94 #include <svx/svdoutl.hxx>
95 #include <editeng/outlobj.hxx>
96 #include <editeng/paperinf.hxx>
97 #include <tools/stream.hxx>
98 #include <basegfx/polygon/b2dpolygon.hxx>
99 #include <basegfx/polygon/b2dpolypolygon.hxx>
100 #include <basegfx/range/b2drange.hxx>
101 #include <vcl/salbtype.hxx> // FRound
102 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
103 #include <drawdoc.hxx>
104
105 using namespace ::com::sun::star;
106
107 // einige Hilfs-Funktionen
108 // char
GetSize(const SfxItemSet & rSet,sal_Bool bInP=sal_True)109 inline const SvxFontHeightItem& GetSize(const SfxItemSet& rSet,sal_Bool bInP=sal_True)
110 { return (const SvxFontHeightItem&)rSet.Get( RES_CHRATR_FONTSIZE,bInP); }
GetLRSpace(const SfxItemSet & rSet,sal_Bool bInP=sal_True)111 inline const SvxLRSpaceItem& GetLRSpace(const SfxItemSet& rSet,sal_Bool bInP=sal_True)
112 { return (const SvxLRSpaceItem&)rSet.Get( RES_LR_SPACE,bInP); }
113
114 /* */
115
ImportRTF()116 extern "C" SAL_DLLPUBLIC_EXPORT Reader* SAL_CALL ImportRTF()
117 {
118 return new RtfReader();
119 }
120
121 // Aufruf fuer die allg. Reader-Schnittstelle
Read(SwDoc & rDoc,const String & rBaseURL,SwPaM & rPam,const String &)122 sal_uLong RtfReader::Read( SwDoc &rDoc, const String& rBaseURL, SwPaM &rPam, const String &)
123 {
124 if( !pStrm )
125 {
126 ASSERT( sal_False, "RTF-Read ohne Stream" );
127 return ERR_SWG_READ_ERROR;
128 }
129
130 //JP 18.01.96: Alle Ueberschriften sind normalerweise ohne
131 // Kapitelnummer. Darum hier explizit abschalten
132 // weil das Default jetzt wieder auf AN ist.
133 if( !bInsertMode )
134 {
135 Reader::SetNoOutlineNum( rDoc );
136
137 // MIB 27.09.96: Umrandung uns Abstaende aus Frm-Vorlagen entf.
138 Reader::ResetFrmFmts( rDoc );
139 }
140
141 sal_uLong nRet = 0;
142 SwDocShell *pDocShell(rDoc.GetDocShell());
143 DBG_ASSERT(pDocShell, "no SwDocShell");
144 uno::Reference<document::XDocumentProperties> xDocProps;
145 if (pDocShell) {
146 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
147 pDocShell->GetModel(), uno::UNO_QUERY_THROW);
148 xDocProps.set(xDPS->getDocumentProperties());
149 }
150
151 SvParserRef xParser = new SwRTFParser( &rDoc, xDocProps,
152 rPam, *pStrm, rBaseURL, !bInsertMode );
153 SvParserState eState = xParser->CallParser();
154 if( SVPAR_PENDING != eState && SVPAR_ACCEPTED != eState )
155 {
156 String sErr( String::CreateFromInt32( xParser->GetLineNr() ));
157 sErr += ',';
158 sErr += String::CreateFromInt32( xParser->GetLinePos() );
159
160 nRet = *new StringErrorInfo( ERR_FORMAT_ROWCOL, sErr,
161 ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
162 }
163
164
165 return nRet;
166 }
167
Read(SvStream * pStream,SwDoc & rDoc,const String & rBaseURL,SwPaM & rPam)168 sal_uLong RtfReader::Read(SvStream* pStream, SwDoc& rDoc, const String& rBaseURL, SwPaM& rPam)
169 {
170 pStrm = pStream;
171 return Read(rDoc, rBaseURL, rPam, rBaseURL);
172 }
173
SwRTFParser(SwDoc * pD,uno::Reference<document::XDocumentProperties> i_xDocProps,const SwPaM & rCrsr,SvStream & rIn,const String & rBaseURL,int bReadNewDoc)174 SwRTFParser::SwRTFParser(SwDoc* pD,
175 uno::Reference<document::XDocumentProperties> i_xDocProps,
176 const SwPaM& rCrsr, SvStream& rIn, const String& rBaseURL,
177 int bReadNewDoc) :
178 SvxRTFParser(pD->GetAttrPool(), rIn, i_xDocProps, bReadNewDoc),
179 maParaStyleMapper(*pD),
180 maCharStyleMapper(*pD),
181 maSegments(*this),
182 maInsertedTables(*pD),
183 mpBookmarkStart(0),
184 mpRedlineStack(0),
185 pAuthorInfos(0),
186 pGrfAttrSet(0),
187 pTableNode(0),
188 pOldTblNd(0),
189 pSttNdIdx(0),
190 pRegionEndIdx(0),
191 pDoc(pD),
192 pRelNumRule(new SwRelNumRuleSpaces(*pD, static_cast< sal_Bool >(bReadNewDoc))),
193 pRedlineInsert(0),
194 pRedlineDelete(0),
195 sBaseURL( rBaseURL ),
196 nAktPageDesc(0),
197 nAktFirstPageDesc(0),
198 m_nCurrentBox(0),
199 nInsTblRow(USHRT_MAX),
200 nNewNumSectDef(USHRT_MAX),
201 nRowsToRepeat(0),
202 // --> OD 2008-12-22 #i83368#
203 mbReadCellWhileReadSwFly( false ),
204 // <--
205 bTrowdRead(0),
206 nReadFlyDepth(0),
207 nZOrder(0)
208 {
209 mbIsFootnote = mbReadNoTbl = bReadSwFly = bSwPageDesc = bStyleTabValid =
210 bInPgDscTbl = bNewNumList = false;
211 bFirstContinue = true;
212 bContainsPara = false;
213 bContainsTablePara = false;
214 bNestedField = false;
215 bForceNewTable = false;
216
217 pPam = new SwPaM( *rCrsr.GetPoint() );
218 SetInsPos( SwxPosition( pPam ) );
219 SetChkStyleAttr( 0 != bReadNewDoc );
220 SetCalcValue( sal_False );
221 SetReadDocInfo( sal_True );
222
223 // diese sollen zusaetzlich ueber \pard zurueck gesetzt werden
224 sal_uInt16 temp;
225 temp = RES_TXTATR_CHARFMT; AddPlainAttr( temp );
226 temp = RES_PAGEDESC; AddPardAttr( temp );
227 temp = RES_BREAK; AddPardAttr( temp );
228 temp = RES_PARATR_NUMRULE; AddPardAttr( temp );
229 temp = FN_PARAM_NUM_LEVEL; AddPardAttr( temp );
230 }
231
232 // Aufruf des Parsers
CallParser()233 SvParserState SwRTFParser::CallParser()
234 {
235 mbReadNoTbl = false;
236 bFirstContinue = true;
237
238 rInput.Seek(STREAM_SEEK_TO_BEGIN);
239 rInput.ResetError();
240
241 mpRedlineStack = new sw::util::RedlineStack(*pDoc);
242
243 return SvxRTFParser::CallParser();
244 }
245
lcl_UsedPara(SwPaM & rPam)246 bool lcl_UsedPara(SwPaM &rPam)
247 {
248 const SwCntntNode* pCNd;
249 const SfxItemSet* pSet;
250 if( rPam.GetPoint()->nContent.GetIndex() ||
251 ( 0 != ( pCNd = rPam.GetCntntNode()) &&
252 0 != ( pSet = pCNd->GetpSwAttrSet()) &&
253 ( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, sal_False ) ||
254 SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, sal_False ))))
255 return true;
256 return false;
257 }
258
Continue(int nToken)259 void SwRTFParser::Continue( int nToken )
260 {
261 if( bFirstContinue )
262 {
263 bFirstContinue = sal_False;
264
265 if (IsNewDoc())
266 {
267 //
268 // COMPATIBILITY FLAGS START
269 //
270 pDoc->set(IDocumentSettingAccess::PARA_SPACE_MAX, true);
271 pDoc->set(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES, true);
272 pDoc->set(IDocumentSettingAccess::TAB_COMPAT, true);
273 pDoc->set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, true);
274 pDoc->set(IDocumentSettingAccess::USE_HIRES_VIRTUAL_DEVICE, true);
275 pDoc->set(IDocumentSettingAccess::ADD_FLY_OFFSETS, true);
276 pDoc->set(IDocumentSettingAccess::ADD_EXT_LEADING, true);
277 pDoc->set(IDocumentSettingAccess::OLD_NUMBERING, false);
278 pDoc->set(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, false );
279 pDoc->set(IDocumentSettingAccess::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, false);
280 pDoc->set(IDocumentSettingAccess::OLD_LINE_SPACING, false);
281 pDoc->set(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS, true);
282 pDoc->set(IDocumentSettingAccess::USE_FORMER_OBJECT_POS, false);
283 pDoc->set(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING, false);
284 pDoc->set(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION, true);
285 pDoc->set(IDocumentSettingAccess::DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, false); // --> FME 2005-08-11 #i53199#
286 // --> FME 2006-02-10 #131283#
287 pDoc->set(IDocumentSettingAccess::TABLE_ROW_KEEP, true);
288 pDoc->set(IDocumentSettingAccess::IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION, true);
289
290 //
291 // COMPATIBILITY FLAGS END
292 //
293 }
294
295 // einen temporaeren Index anlegen, auf Pos 0 so wird er nicht bewegt!
296 pSttNdIdx = new SwNodeIndex( pDoc->GetNodes() );
297 if( !IsNewDoc() ) // in ein Dokument einfuegen ?
298 {
299 const SwPosition* pPos = pPam->GetPoint();
300 SwTxtNode* pSttNd = pPos->nNode.GetNode().GetTxtNode();
301
302 pDoc->SplitNode( *pPos, false );
303
304 *pSttNdIdx = pPos->nNode.GetIndex()-1;
305 pDoc->SplitNode( *pPos, false );
306
307 SwPaM aInsertionRangePam( *pPos );
308
309 pPam->Move( fnMoveBackward );
310
311 // #106634# split any redline over the insertion point
312 aInsertionRangePam.SetMark();
313 *aInsertionRangePam.GetPoint() = *pPam->GetPoint();
314 aInsertionRangePam.Move( fnMoveBackward );
315 pDoc->SplitRedline( aInsertionRangePam );
316
317 pDoc->SetTxtFmtColl( *pPam, pDoc->GetTxtCollFromPool
318 ( RES_POOLCOLL_STANDARD, false ));
319
320 // verhinder das einlesen von Tabellen in Fussnoten / Tabellen
321 sal_uLong nNd = pPos->nNode.GetIndex();
322 mbReadNoTbl = 0 != pSttNd->FindTableNode() ||
323 ( nNd < pDoc->GetNodes().GetEndOfInserts().GetIndex() &&
324 pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() < nNd );
325 }
326
327 // Laufbalken anzeigen, aber nur bei synchronem Call
328 sal_uLong nCurrPos = rInput.Tell();
329 rInput.Seek(STREAM_SEEK_TO_END);
330 rInput.ResetError();
331 ::StartProgress( STR_STATSTR_W4WREAD, 0, rInput.Tell(), pDoc->GetDocShell());
332 rInput.Seek( nCurrPos );
333 rInput.ResetError();
334 }
335
336 SvxRTFParser::Continue( nToken );
337
338 if( SVPAR_PENDING == GetStatus() )
339 return ; // weiter gehts beim naechsten mal
340
341 pRelNumRule->SetNumRelSpaces( *pDoc );
342
343 // den Start wieder korrigieren
344 if( !IsNewDoc() && pSttNdIdx->GetIndex() )
345 {
346 //die Flys muessen zuerst zurecht gerueckt werden, denn sonst wird
347 // ein am 1. Absatz verankerter Fly falsch eingefuegt
348 if( SVPAR_ACCEPTED == eState )
349 {
350 if( aFlyArr.Count() )
351 SetFlysInDoc();
352 pRelNumRule->SetOultineRelSpaces( *pSttNdIdx, pPam->GetPoint()->nNode );
353 }
354
355 SwTxtNode* pTxtNode = pSttNdIdx->GetNode().GetTxtNode();
356 SwNodeIndex aNxtIdx( *pSttNdIdx );
357 if( pTxtNode && pTxtNode->CanJoinNext( &aNxtIdx ))
358 {
359 xub_StrLen nStt = pTxtNode->GetTxt().Len();
360 // wenn der Cursor noch in dem Node steht, dann setze in an das Ende
361 if( pPam->GetPoint()->nNode == aNxtIdx )
362 {
363 pPam->GetPoint()->nNode = *pSttNdIdx;
364 pPam->GetPoint()->nContent.Assign( pTxtNode, nStt );
365 }
366
367 #ifdef DBG_UTIL
368 // !!! sollte nicht moeglich sein, oder ??
369 ASSERT( pSttNdIdx->GetIndex()+1 != pPam->GetBound( sal_True ).nNode.GetIndex(),
370 "Pam.Bound1 steht noch im Node" );
371 ASSERT( pSttNdIdx->GetIndex()+1 != pPam->GetBound( sal_False ).nNode.GetIndex(),
372 "Pam.Bound2 steht noch im Node" );
373
374 if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( sal_True ).nNode.GetIndex() )
375 {
376 xub_StrLen nCntPos = pPam->GetBound( sal_True ).nContent.GetIndex();
377 pPam->GetBound( sal_True ).nContent.Assign( pTxtNode,
378 pTxtNode->GetTxt().Len() + nCntPos );
379 }
380 if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( sal_False ).nNode.GetIndex() )
381 {
382 xub_StrLen nCntPos = pPam->GetBound( sal_False ).nContent.GetIndex();
383 pPam->GetBound( sal_False ).nContent.Assign( pTxtNode,
384 pTxtNode->GetTxt().Len() + nCntPos );
385 }
386 #endif
387 // Zeichen Attribute beibehalten!
388 SwTxtNode* pDelNd = aNxtIdx.GetNode().GetTxtNode();
389 if( pTxtNode->GetTxt().Len() )
390 pDelNd->FmtToTxtAttr( pTxtNode );
391 else
392 pTxtNode->ChgFmtColl( pDelNd->GetTxtColl() );
393 pTxtNode->JoinNext();
394 }
395 }
396
397 if( SVPAR_ACCEPTED == eState )
398 {
399 // den letzen Bereich wieder zumachen
400 if( pRegionEndIdx )
401 {
402 // JP 06.01.00: Task 71411 - the last section in WW are not a
403 // balanced Section.
404 if( !GetVersionNo() )
405 {
406 SwSectionNode* pSectNd = pRegionEndIdx->GetNode().
407 StartOfSectionNode()->GetSectionNode();
408 if( pSectNd )
409 pSectNd->GetSection().GetFmt()->SetFmtAttr(
410 SwFmtNoBalancedColumns( sal_True ) );
411 }
412
413 DelLastNode();
414 pPam->GetPoint()->nNode = *pRegionEndIdx;
415 pPam->Move( fnMoveForward, fnGoNode );
416 delete pRegionEndIdx, pRegionEndIdx = 0;
417 }
418
419 sal_uInt16 nPageDescOffset = pDoc->GetPageDescCnt();
420 maSegments.InsertSegments(IsNewDoc());
421 UpdatePageDescs(*pDoc, nPageDescOffset);
422 //$flr folloing garbe collecting code has been moved from the previous procedure
423 // UpdatePageDescs to here in order to fix bug #117882#
424 rtfSections::myrDummyIter aDEnd = maSegments.maDummyPageNos.rend();
425 for (rtfSections::myrDummyIter aI = maSegments.maDummyPageNos.rbegin(); aI != aDEnd; ++aI)
426 pDoc->DelPageDesc(*aI);
427
428 if( aFlyArr.Count() )
429 SetFlysInDoc();
430
431 // jetzt noch den letzten ueberfluessigen Absatz loeschen
432 SwPosition* pPos = pPam->GetPoint();
433 if( !pPos->nContent.GetIndex() )
434 {
435 SwTxtNode* pAktNd;
436 sal_uLong nNodeIdx = pPos->nNode.GetIndex();
437 if( IsNewDoc() )
438 {
439 SwNode* pTmp = pDoc->GetNodes()[ nNodeIdx -1 ];
440 if( pTmp->IsCntntNode() && !pTmp->FindTableNode() )
441 {
442 // --> FME 2006-02-15 #131200# Do not delete the paragraph
443 // if it has anchored objects:
444 bool bAnchoredObjs = false;
445 const SwSpzFrmFmts* pFrmFmts = pDoc->GetSpzFrmFmts();
446 if ( pFrmFmts && pFrmFmts->Count() )
447 {
448 for ( sal_uInt16 nI = pFrmFmts->Count(); nI; --nI )
449 {
450 const SwFmtAnchor & rAnchor = (*pFrmFmts)[ nI - 1 ]->GetAnchor();
451 if ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
452 (FLY_AT_CHAR == rAnchor.GetAnchorId()))
453 {
454 const SwPosition * pObjPos = rAnchor.GetCntntAnchor();
455 if ( pObjPos && nNodeIdx == pObjPos->nNode.GetIndex() )
456 {
457 bAnchoredObjs = true;
458 break;
459 }
460 }
461 }
462 }
463 // <--
464
465 if ( !bAnchoredObjs )
466 DelLastNode();
467 }
468 }
469 else if (0 != (pAktNd = pDoc->GetNodes()[nNodeIdx]->GetTxtNode()))
470 {
471 if( pAktNd->CanJoinNext( &pPos->nNode ))
472 {
473 SwTxtNode* pNextNd = pPos->nNode.GetNode().GetTxtNode();
474 pPos->nContent.Assign( pNextNd, 0 );
475 pPam->SetMark(); pPam->DeleteMark();
476 pNextNd->JoinPrev();
477 }
478 else if( !pAktNd->GetTxt().Len() &&
479 pAktNd->StartOfSectionIndex()+2 <
480 pAktNd->EndOfSectionIndex() )
481 {
482 pPos->nContent.Assign( 0, 0 );
483 pPam->SetMark(); pPam->DeleteMark();
484 pDoc->GetNodes().Delete( pPos->nNode, 1 );
485 pPam->Move( fnMoveBackward );
486 }
487 }
488 }
489 // nun noch das SplitNode vom Ende aufheben
490 else if( !IsNewDoc() )
491 {
492 if( pPos->nContent.GetIndex() ) // dann gabs am Ende kein \par,
493 pPam->Move( fnMoveForward, fnGoNode ); // als zum naechsten Node
494 SwTxtNode* pTxtNode = pPos->nNode.GetNode().GetTxtNode();
495 SwNodeIndex aPrvIdx( pPos->nNode );
496 if( pTxtNode && pTxtNode->CanJoinPrev( &aPrvIdx ) &&
497 *pSttNdIdx <= aPrvIdx )
498 {
499 // eigentlich muss hier ein JoinNext erfolgen, aber alle Cursor
500 // usw. sind im pTxtNode angemeldet, so dass der bestehen
501 // bleiben MUSS.
502
503 // Absatz in Zeichen-Attribute umwandeln, aus dem Prev die
504 // Absatzattribute und die Vorlage uebernehmen!
505 SwTxtNode* pPrev = aPrvIdx.GetNode().GetTxtNode();
506 pTxtNode->ChgFmtColl( pPrev->GetTxtColl() );
507 pTxtNode->FmtToTxtAttr( pPrev );
508 pTxtNode->ResetAllAttr();
509
510 if( pPrev->HasSwAttrSet() )
511 pTxtNode->SetAttr( *pPrev->GetpSwAttrSet() );
512
513 if( &pPam->GetBound(sal_True).nNode.GetNode() == pPrev )
514 pPam->GetBound(sal_True).nContent.Assign( pTxtNode, 0 );
515 if( &pPam->GetBound(sal_False).nNode.GetNode() == pPrev )
516 pPam->GetBound(sal_False).nContent.Assign( pTxtNode, 0 );
517
518 pTxtNode->JoinPrev();
519 }
520 }
521 }
522 delete pSttNdIdx, pSttNdIdx = 0;
523 delete pRegionEndIdx, pRegionEndIdx = 0;
524 RemoveUnusedNumRules();
525
526 pDoc->SetUpdateExpFldStat(true);
527 pDoc->SetInitDBFields(true);
528
529 // Laufbalken bei asynchronen Call nicht einschalten !!!
530 ::EndProgress( pDoc->GetDocShell() );
531 }
532
SetCols(SwFrmFmt & rFmt,const rtfSection & rSection,sal_uInt16 nNettoWidth)533 bool rtfSections::SetCols(SwFrmFmt &rFmt, const rtfSection &rSection,
534 sal_uInt16 nNettoWidth)
535 {
536 //sprmSCcolumns - Anzahl der Spalten - 1
537 sal_uInt16 nCols = static_cast< sal_uInt16 >(rSection.NoCols());
538
539 if (nCols < 2)
540 return false; // keine oder bloedsinnige Spalten
541
542 SwFmtCol aCol; // Erzeuge SwFmtCol
543
544 //sprmSDxaColumns - Default-Abstand 1.25 cm
545 sal_uInt16 nColSpace = static_cast< sal_uInt16 >(rSection.StandardColSeperation());
546
547 aCol.Init( nCols, nColSpace, nNettoWidth );
548
549 // not SFEvenlySpaced
550 if (rSection.maPageInfo.maColumns.size())
551 {
552 aCol._SetOrtho(false);
553 sal_uInt16 nWishWidth = 0, nHalfPrev = 0;
554 for (sal_uInt16 n=0, i=0;
555 (static_cast<size_t>(n)+1) < rSection.maPageInfo.maColumns.size() && i < nCols;
556 n += 2, ++i)
557 {
558 SwColumn* pCol = aCol.GetColumns()[ i ];
559 pCol->SetLeft( nHalfPrev );
560 sal_uInt16 nSp = static_cast< sal_uInt16 >(rSection.maPageInfo.maColumns[ n+1 ]);
561 nHalfPrev = nSp / 2;
562 pCol->SetRight( nSp - nHalfPrev );
563 pCol->SetWishWidth( static_cast< sal_uInt16 >(rSection.maPageInfo.maColumns[ n ]) +
564 pCol->GetLeft() + pCol->GetRight());
565 nWishWidth = nWishWidth + pCol->GetWishWidth();
566 }
567 aCol.SetWishWidth( nWishWidth );
568 }
569
570 rFmt.SetFmtAttr(aCol);
571 return true;
572 }
573
SetPage(SwPageDesc & rInPageDesc,SwFrmFmt & rFmt,const rtfSection & rSection,bool bIgnoreCols)574 void rtfSections::SetPage(SwPageDesc &rInPageDesc, SwFrmFmt &rFmt,
575 const rtfSection &rSection, bool bIgnoreCols)
576 {
577 // 1. Orientierung
578 rInPageDesc.SetLandscape(rSection.IsLandScape());
579
580 // 2. Papiergroesse
581 SwFmtFrmSize aSz(rFmt.GetFrmSize());
582 aSz.SetWidth(rSection.GetPageWidth());
583 aSz.SetHeight(rSection.GetPageHeight());
584 rFmt.SetFmtAttr(aSz);
585
586 rFmt.SetFmtAttr(
587 SvxLRSpaceItem(rSection.GetPageLeft(), rSection.GetPageRight(), 0, 0, RES_LR_SPACE));
588
589 if (!bIgnoreCols)
590 {
591 SetCols(rFmt, rSection, static_cast< sal_uInt16 >(rSection.GetPageWidth() -
592 rSection.GetPageLeft() - rSection.GetPageRight()));
593 }
594
595 rFmt.SetFmtAttr(rSection.maPageInfo.maBox);
596 }
597
HasHeader(const SwFrmFmt & rFmt)598 bool HasHeader(const SwFrmFmt &rFmt)
599 {
600 const SfxPoolItem *pHd;
601 if (SFX_ITEM_SET == rFmt.GetItemState(RES_HEADER, false, &pHd))
602 return ((const SwFmtHeader *)(pHd))->IsActive();
603 return false;
604 }
605
HasFooter(const SwFrmFmt & rFmt)606 bool HasFooter(const SwFrmFmt &rFmt)
607 {
608 const SfxPoolItem *pFt;
609 if (SFX_ITEM_SET == rFmt.GetItemState(RES_FOOTER, false, &pFt))
610 return ((const SwFmtFooter *)(pFt))->IsActive();
611 return false;
612 }
613
GetPageULData(const rtfSection & rSection,bool bFirst,rtfSections::wwULSpaceData & rData)614 void rtfSections::GetPageULData(const rtfSection &rSection, bool bFirst,
615 rtfSections::wwULSpaceData& rData)
616 {
617 short nWWUp = static_cast< short >(rSection.maPageInfo.mnMargtsxn);
618 short nWWLo = static_cast< short >(rSection.maPageInfo.mnMargbsxn);
619 short nWWHTop = static_cast< short >(rSection.maPageInfo.mnHeadery);
620 short nWWFBot = static_cast< short >(rSection.maPageInfo.mnFootery);
621
622 if (bFirst)
623 {
624 if (
625 rSection.mpTitlePage && HasHeader(rSection.mpTitlePage->GetMaster())
626 )
627 {
628 rData.bHasHeader = true;
629 }
630 }
631 else
632 {
633 if (rSection.mpPage &&
634 (
635 HasHeader(rSection.mpPage->GetMaster())
636 || HasHeader(rSection.mpPage->GetLeft())
637 )
638 )
639 {
640 rData.bHasHeader = true;
641 }
642 }
643
644 if( rData.bHasHeader )
645 {
646 rData.nSwUp = nWWHTop; // Header -> umrechnen, see ww8par6.cxx
647
648 if ( nWWUp > 0 && nWWUp >= nWWHTop )
649 rData.nSwHLo = nWWUp - nWWHTop;
650 else
651 rData.nSwHLo = 0;
652
653 if (rData.nSwHLo < cMinHdFtHeight)
654 rData.nSwHLo = cMinHdFtHeight;
655 }
656 else // kein Header -> Up einfach uebernehmen
657 rData.nSwUp = Abs(nWWUp);
658
659 if (bFirst)
660 {
661 if (
662 rSection.mpTitlePage &&
663 HasFooter(rSection.mpTitlePage->GetMaster())
664 )
665 {
666 rData.bHasFooter = true;
667 }
668 }
669 else
670 {
671 if (rSection.mpPage &&
672 (
673 HasFooter(rSection.mpPage->GetMaster())
674 || HasFooter(rSection.mpPage->GetLeft())
675 )
676 )
677 {
678 rData.bHasFooter = true;
679 }
680 }
681
682 if( rData.bHasFooter )
683 {
684 rData.nSwLo = nWWFBot; // Footer -> Umrechnen
685 if ( nWWLo > 0 && nWWLo >= nWWFBot )
686 rData.nSwFUp = nWWLo - nWWFBot;
687 else
688 rData.nSwFUp = 0;
689
690 if (rData.nSwFUp < cMinHdFtHeight)
691 rData.nSwFUp = cMinHdFtHeight;
692 }
693 else // kein Footer -> Lo einfach uebernehmen
694 rData.nSwLo = Abs(nWWLo);
695 }
696
SetPageULSpaceItems(SwFrmFmt & rFmt,rtfSections::wwULSpaceData & rData)697 void rtfSections::SetPageULSpaceItems(SwFrmFmt &rFmt,
698 rtfSections::wwULSpaceData& rData)
699 {
700 if (rData.bHasHeader) // ... und Header-Lower setzen
701 {
702 //Kopfzeilenhoehe minimal sezten
703 if (SwFrmFmt* pHdFmt = (SwFrmFmt*)rFmt.GetHeader().GetHeaderFmt())
704 {
705 pHdFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwHLo));
706 SvxULSpaceItem aHdUL(pHdFmt->GetULSpace());
707 aHdUL.SetLower( rData.nSwHLo - cMinHdFtHeight );
708 pHdFmt->SetFmtAttr(aHdUL);
709 pHdFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
710 RES_HEADER_FOOTER_EAT_SPACING, true));
711 }
712 }
713
714 if (rData.bHasFooter) // ... und Footer-Upper setzen
715 {
716 if (SwFrmFmt* pFtFmt = (SwFrmFmt*)rFmt.GetFooter().GetFooterFmt())
717 {
718 pFtFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwFUp));
719 SvxULSpaceItem aFtUL(pFtFmt->GetULSpace());
720 aFtUL.SetUpper( rData.nSwFUp - cMinHdFtHeight );
721 pFtFmt->SetFmtAttr(aFtUL);
722 pFtFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
723 RES_HEADER_FOOTER_EAT_SPACING, true));
724 }
725 }
726
727 SvxULSpaceItem aUL(rData.nSwUp, rData.nSwLo, RES_UL_SPACE ); // Page-UL setzen
728 rFmt.SetFmtAttr(aUL);
729 }
730
SetSegmentToPageDesc(const rtfSection & rSection,bool bTitlePage,bool bIgnoreCols)731 void rtfSections::SetSegmentToPageDesc(const rtfSection &rSection,
732 bool bTitlePage, bool bIgnoreCols)
733 {
734 SwPageDesc &rPage = bTitlePage ? *rSection.mpTitlePage : *rSection.mpPage;
735
736 // SetNumberingType(rSection, rPage);
737
738 SwFrmFmt &rFmt = rPage.GetMaster();
739 // mrReader.SetDocumentGrid(rFmt, rSection);
740
741 wwULSpaceData aULData;
742 GetPageULData(rSection, bTitlePage, aULData);
743 SetPageULSpaceItems(rFmt, aULData);
744
745 SetPage(rPage, rFmt, rSection, bIgnoreCols);
746
747 UseOnPage ePage = rPage.ReadUseOn();
748 if(ePage & nsUseOnPage::PD_ALL)
749 {
750 SwFrmFmt &rFmtLeft = rPage.GetLeft();
751 SetPageULSpaceItems(rFmtLeft, aULData);
752 SetPage(rPage, rFmtLeft, rSection, bIgnoreCols);
753 }
754
755 }
756
CopyFrom(const SwPageDesc & rFrom,SwPageDesc & rDest)757 void rtfSections::CopyFrom(const SwPageDesc &rFrom, SwPageDesc &rDest)
758 {
759 UseOnPage ePage = rFrom.ReadUseOn();
760 rDest.WriteUseOn(ePage);
761
762 mrReader.pDoc->CopyHeader(rFrom.GetMaster(), rDest.GetMaster());
763 SwFrmFmt &rDestFmt = rDest.GetMaster();
764 rDestFmt.SetFmtAttr(rFrom.GetMaster().GetHeader());
765 mrReader.pDoc->CopyHeader(rFrom.GetLeft(), rDest.GetLeft());
766 mrReader.pDoc->CopyFooter(rFrom.GetMaster(), rDest.GetMaster());
767 mrReader.pDoc->CopyFooter(rFrom.GetLeft(), rDest.GetLeft());
768 }
769
MoveFrom(SwPageDesc & rFrom,SwPageDesc & rDest)770 void rtfSections::MoveFrom(SwPageDesc &rFrom, SwPageDesc &rDest)
771 {
772 UseOnPage ePage = rFrom.ReadUseOn();
773 rDest.WriteUseOn(ePage);
774
775 SwFrmFmt &rDestMaster = rDest.GetMaster();
776 SwFrmFmt &rFromMaster = rFrom.GetMaster();
777 rDestMaster.SetFmtAttr(rFromMaster.GetHeader());
778 rDestMaster.SetFmtAttr(rFromMaster.GetFooter());
779 //rFromMaster.SetAttr(SwFmtHeader()); //$flr uncommented due to bug fix #117882#
780 //rFromMaster.SetAttr(SwFmtFooter()); //$flr uncommented due to bug fix #117882#
781
782 SwFrmFmt &rDestLeft = rDest.GetLeft();
783 SwFrmFmt &rFromLeft = rFrom.GetLeft();
784 rDestLeft.SetFmtAttr(rFromLeft.GetHeader());
785 rDestLeft.SetFmtAttr(rFromLeft.GetFooter());
786 //rFromLeft.SetAttr(SwFmtHeader()); //$flr uncommented due to bug fix #117882#
787 //rFromLeft.SetAttr(SwFmtFooter()); //$flr uncommented due to bug fix #117882#
788 }
789
SetHdFt(rtfSection & rSection)790 void rtfSections::SetHdFt(rtfSection &rSection)
791 {
792 ASSERT(rSection.mpPage, "makes no sense to call without a main page");
793 if (rSection.mpPage && rSection.maPageInfo.mpPageHdFt)
794 {
795 if (rSection.maPageInfo.mbPageHdFtUsed)
796 {
797 MoveFrom(*rSection.maPageInfo.mpPageHdFt, *rSection.mpPage);
798 rSection.maPageInfo.mbPageHdFtUsed = false;
799 rSection.maPageInfo.mpPageHdFt = rSection.mpPage;
800 }
801 else
802 CopyFrom(*rSection.maPageInfo.mpPageHdFt, *rSection.mpPage);
803 }
804
805 if (rSection.mpTitlePage && rSection.maPageInfo.mpTitlePageHdFt)
806 {
807 if (rSection.maPageInfo.mbTitlePageHdFtUsed)
808 {
809 MoveFrom(*rSection.maPageInfo.mpTitlePageHdFt,
810 *rSection.mpTitlePage);
811 rSection.maPageInfo.mbTitlePageHdFtUsed = false;
812 rSection.maPageInfo.mpTitlePageHdFt = rSection.mpTitlePage;
813 }
814 else
815 {
816 CopyFrom(*rSection.maPageInfo.mpTitlePageHdFt,
817 *rSection.mpTitlePage);
818 }
819 }
820 }
821
InsertSection(SwPaM & rMyPaM,rtfSection & rSection)822 SwSectionFmt *rtfSections::InsertSection(SwPaM& rMyPaM, rtfSection &rSection)
823 {
824 SwSectionData aSectionData(CONTENT_SECTION,
825 mrReader.pDoc->GetUniqueSectionName());
826
827 SfxItemSet aSet( mrReader.pDoc->GetAttrPool(), aFrmFmtSetRange );
828
829 sal_uInt8 nRTLPgn = maSegments.empty() ? 0 : maSegments.back().IsBiDi();
830 aSet.Put(SvxFrameDirectionItem(
831 nRTLPgn ? FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR));
832
833 rSection.mpSection =
834 mrReader.pDoc->InsertSwSection( rMyPaM, aSectionData, 0, &aSet );
835 ASSERT(rSection.mpSection, "section not inserted!");
836 if (!rSection.mpSection)
837 return 0;
838
839 SwPageDesc *pPage = 0;
840 mySegrIter aEnd = maSegments.rend();
841 for (mySegrIter aIter = maSegments.rbegin(); aIter != aEnd; ++aIter)
842 {
843 pPage = aIter->mpPage;
844 if (pPage)
845 break;
846 }
847
848 ASSERT(pPage, "no page outside this section!");
849
850 if (!pPage)
851 pPage = &mrReader.pDoc->_GetPageDesc(0);
852
853 if (!pPage)
854 return 0;
855
856 SwFrmFmt& rFmt = pPage->GetMaster();
857 const SwFmtFrmSize& rSz = rFmt.GetFrmSize();
858 const SvxLRSpaceItem& rLR = rFmt.GetLRSpace();
859 SwTwips nWidth = rSz.GetWidth();
860 long nLeft = rLR.GetTxtLeft();
861 long nRight = rLR.GetRight();
862
863 SwSectionFmt *pFmt = rSection.mpSection->GetFmt();
864 ASSERT(pFmt, "impossible");
865 if (!pFmt)
866 return 0;
867 SetCols(*pFmt, rSection, (sal_uInt16)(nWidth - nLeft - nRight) );
868
869 return pFmt;
870 }
871
InsertSegments(bool bNewDoc)872 void rtfSections::InsertSegments(bool bNewDoc)
873 {
874 sal_uInt16 nDesc(0);
875 mySegIter aEnd = maSegments.end();
876 mySegIter aStart = maSegments.begin();
877 for (mySegIter aIter = aStart; aIter != aEnd; ++aIter)
878 {
879 mySegIter aNext = aIter+1;
880
881 bool bInsertSection = aIter != aStart ? aIter->IsContinous() : false;
882
883 if (!bInsertSection)
884 {
885 /*
886 If a cont section follow this section then we won't be
887 creating a page desc with 2+ cols as we cannot host a one
888 col section in a 2+ col pagedesc and make it look like
889 word. But if the current section actually has columns then
890 we are forced to insert a section here as well as a page
891 descriptor.
892 */
893
894 /*
895 Note for the future:
896 If we want to import "protected sections" the here is
897 where we would also test for that and force a section
898 insertion if that was true.
899 */
900 bool bIgnoreCols = false;
901 if (aNext != aEnd && aNext->IsContinous())
902 {
903 bIgnoreCols = true;
904 if (aIter->NoCols() > 1)
905 bInsertSection = true;
906 }
907
908 if (aIter->HasTitlePage())
909 {
910 if (bNewDoc && aIter == aStart)
911 {
912 aIter->mpTitlePage =
913 mrReader.pDoc->GetPageDescFromPool(RES_POOLPAGE_FIRST);
914 }
915 else
916 {
917 sal_uInt16 nPos = mrReader.pDoc->MakePageDesc(
918 ViewShell::GetShellRes()->GetPageDescName(nDesc)
919 , 0, false);
920 aIter->mpTitlePage = &mrReader.pDoc->_GetPageDesc(nPos);
921 }
922 ASSERT(aIter->mpTitlePage, "no page!");
923 if (!aIter->mpTitlePage)
924 continue;
925
926 SetSegmentToPageDesc(*aIter, true, bIgnoreCols);
927 }
928
929 if (!bNewDoc && aIter == aStart)
930 continue;
931 else if (bNewDoc && aIter == aStart)
932 {
933 aIter->mpPage =
934 mrReader.pDoc->GetPageDescFromPool(RES_POOLPAGE_STANDARD);
935 }
936 else
937 {
938 sal_uInt16 nPos = mrReader.pDoc->MakePageDesc(
939 ViewShell::GetShellRes()->GetPageDescName(nDesc,
940 false, aIter->HasTitlePage()),
941 aIter->mpTitlePage, false);
942 aIter->mpPage = &mrReader.pDoc->_GetPageDesc(nPos);
943 }
944 ASSERT(aIter->mpPage, "no page!");
945 if (!aIter->mpPage)
946 continue;
947
948 SetHdFt(*aIter);
949
950 if (aIter->mpTitlePage)
951 SetSegmentToPageDesc(*aIter, true, bIgnoreCols);
952 SetSegmentToPageDesc(*aIter, false, bIgnoreCols);
953
954 SwFmtPageDesc aPgDesc(aIter->HasTitlePage() ?
955 aIter->mpTitlePage : aIter->mpPage);
956
957 if (aIter->mpTitlePage)
958 aIter->mpTitlePage->SetFollow(aIter->mpPage);
959
960 if (aIter->PageRestartNo() ||
961 ((aIter == aStart) && aIter->PageStartAt() != 1))
962 aPgDesc.SetNumOffset( static_cast< sal_uInt16 >(aIter->PageStartAt()) );
963
964 /*
965 If its a table here, apply the pagebreak to the table
966 properties, otherwise we add it to the para at this
967 position
968 */
969 if (aIter->maStart.GetNode().IsTableNode())
970 {
971 SwTable& rTable =
972 aIter->maStart.GetNode().GetTableNode()->GetTable();
973 SwFrmFmt* pApply = rTable.GetFrmFmt();
974 ASSERT(pApply, "impossible");
975 if (pApply)
976 pApply->SetFmtAttr(aPgDesc);
977 }
978 else
979 {
980 SwPosition aPamStart(aIter->maStart);
981 aPamStart.nContent.Assign(
982 aIter->maStart.GetNode().GetCntntNode(), 0);
983 SwPaM aPage(aPamStart);
984
985 mrReader.pDoc->InsertPoolItem(aPage, aPgDesc, 0);
986 }
987 ++nDesc;
988 }
989
990 SwTxtNode* pTxtNd = 0;
991 if (bInsertSection)
992 {
993 SwPaM aSectPaM(*mrReader.pPam);
994 SwNodeIndex aAnchor(aSectPaM.GetPoint()->nNode);
995 if (aNext != aEnd)
996 {
997 aAnchor = aNext->maStart;
998 aSectPaM.GetPoint()->nNode = aAnchor;
999 aSectPaM.GetPoint()->nContent.Assign(
1000 aNext->maStart.GetNode().GetCntntNode(), 0);
1001 aSectPaM.Move(fnMoveBackward);
1002 }
1003
1004 const SwPosition* pPos = aSectPaM.GetPoint();
1005 SwTxtNode const*const pSttNd = pPos->nNode.GetNode().GetTxtNode();
1006 const SwTableNode* pTableNd = pSttNd ? pSttNd->FindTableNode() : 0;
1007 if (pTableNd)
1008 {
1009 pTxtNd =
1010 mrReader.pDoc->GetNodes().MakeTxtNode(aAnchor,
1011 mrReader.pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT ));
1012
1013 aSectPaM.GetPoint()->nNode = SwNodeIndex(*pTxtNd);
1014 aSectPaM.GetPoint()->nContent.Assign(
1015 aSectPaM.GetCntntNode(), 0);
1016 }
1017
1018 aSectPaM.SetMark();
1019
1020 aSectPaM.GetPoint()->nNode = aIter->maStart;
1021 aSectPaM.GetPoint()->nContent.Assign(
1022 aSectPaM.GetCntntNode(), 0);
1023
1024 SwSectionFmt *pRet = InsertSection(aSectPaM, *aIter);
1025 //The last section if continuous is always unbalanced
1026 if (aNext == aEnd && pRet)
1027 pRet->SetFmtAttr(SwFmtNoBalancedColumns(true));
1028 }
1029
1030 if (pTxtNd)
1031 {
1032 SwNodeIndex aIdx(*pTxtNd);
1033 SwPosition aPos(aIdx);
1034 SwPaM aTest(aPos);
1035 mrReader.pDoc->DelFullPara(aTest);
1036 pTxtNd = 0;
1037 }
1038 }
1039 }
1040
1041 namespace sw{
1042 namespace util{
1043
InsertedTableClient(SwTableNode & rNode)1044 InsertedTableClient::InsertedTableClient(SwTableNode & rNode)
1045 {
1046 rNode.Add(this);
1047 }
1048
GetTableNode()1049 SwTableNode * InsertedTableClient::GetTableNode()
1050 {
1051 return dynamic_cast<SwTableNode *> (GetRegisteredInNonConst());
1052 }
1053
InsertedTablesManager(const SwDoc & rDoc)1054 InsertedTablesManager::InsertedTablesManager(const SwDoc &rDoc)
1055 : mbHasRoot(rDoc.GetCurrentLayout()) //swmod 080218
1056 {
1057 }
1058
DelAndMakeTblFrms()1059 void InsertedTablesManager::DelAndMakeTblFrms()
1060 {
1061 if (!mbHasRoot)
1062 return;
1063 TblMapIter aEnd = maTables.end();
1064 for (TblMapIter aIter = maTables.begin(); aIter != aEnd; ++aIter)
1065 {
1066 // exitiert schon ein Layout, dann muss an dieser Tabelle die BoxFrames
1067 // neu erzeugt
1068 SwTableNode *pTable = aIter->first->GetTableNode();
1069 ASSERT(pTable, "Why no expected table");
1070 if (pTable)
1071 {
1072 SwFrmFmt * pFrmFmt = pTable->GetTable().GetFrmFmt();
1073
1074 if (pFrmFmt != NULL)
1075 {
1076 SwNodeIndex *pIndex = aIter->second;
1077 pTable->DelFrms();
1078 pTable->MakeFrms(pIndex);
1079 }
1080 }
1081 }
1082 }
1083
InsertTable(SwTableNode & rTableNode,SwPaM & rPaM)1084 void InsertedTablesManager::InsertTable(SwTableNode &rTableNode, SwPaM &rPaM)
1085 {
1086 if (!mbHasRoot)
1087 return;
1088 //Associate this tablenode with this after position, replace an //old
1089 //node association if necessary
1090
1091 InsertedTableClient * pClient = new InsertedTableClient(rTableNode);
1092
1093 maTables.insert(TblMap::value_type(pClient, &(rPaM.GetPoint()->nNode)));
1094 }
1095 }
1096 }
1097
~SwRTFParser()1098 SwRTFParser::~SwRTFParser()
1099 {
1100 maInsertedTables.DelAndMakeTblFrms();
1101 mpRedlineStack->closeall(*pPam->GetPoint());
1102 delete mpRedlineStack;
1103
1104 delete pSttNdIdx;
1105 delete pRegionEndIdx;
1106 delete pPam;
1107 delete pRelNumRule;
1108
1109 if (aFlyArr.Count())
1110 aFlyArr.DeleteAndDestroy( 0, aFlyArr.Count() );
1111
1112 if (pGrfAttrSet)
1113 DELETEZ( pGrfAttrSet );
1114
1115 DELETEZ( pAuthorInfos );
1116 }
1117
1118 //i19718
ReadShpRslt()1119 void SwRTFParser::ReadShpRslt()
1120 {
1121 int nToken;
1122 while ('}' != (nToken = GetNextToken() ) && IsParserWorking())
1123 {
1124 switch(nToken)
1125 {
1126 case RTF_PAR:
1127 break;
1128 default:
1129 NextToken(nToken);
1130 break;
1131 }
1132 }
1133 SkipToken(-1);
1134 }
1135
ReadShpTxt(String & s)1136 void SwRTFParser::ReadShpTxt(String& s)
1137 {
1138 int nToken;
1139 int level=1;
1140 s.AppendAscii("{\\rtf");
1141 while (level>0 && IsParserWorking())
1142 {
1143 nToken = GetNextToken();
1144 switch(nToken)
1145 {
1146 case RTF_SN:
1147 case RTF_SV:
1148 SkipGroup();
1149 break;
1150 case RTF_TEXTTOKEN:
1151 s.Append(aToken);
1152 break;
1153 case '{':
1154 level++;
1155 s.Append(String::CreateFromAscii("{"));
1156 break;
1157 case '}':
1158 level--;
1159 s.Append(String::CreateFromAscii("}"));
1160 break;
1161 default:
1162 s.Append(aToken);
1163 if (bTokenHasValue) {
1164 s.Append(String::CreateFromInt64(nTokenValue));
1165 }
1166 s.Append(String::CreateFromAscii(" "));
1167 break;
1168 }
1169 }
1170 SkipToken(-1);
1171 }
1172
1173 /*
1174 * #127429#. Very basic support for the "Buchhalternase".
1175 */
ReadDrawingObject()1176 void SwRTFParser::ReadDrawingObject()
1177 {
1178 int nToken;
1179 int level;
1180 level=1;
1181 Rectangle aRect;
1182 ::basegfx::B2DPolygon aPolygon;
1183 ::basegfx::B2DPoint aPoint;
1184 bool bPolygonActive(false);
1185
1186 while (level>0 && IsParserWorking())
1187 {
1188 nToken = GetNextToken();
1189 switch(nToken)
1190 {
1191 case '}':
1192 level--;
1193 break;
1194 case '{':
1195 level++;
1196 break;
1197 case RTF_DPX:
1198 aRect.setX(nTokenValue);
1199 break;
1200 case RTF_DPXSIZE:
1201 aRect.setWidth(nTokenValue);
1202 break;
1203 case RTF_DPY:
1204 aRect.setY(nTokenValue);
1205 break;
1206 case RTF_DPYSIZE:
1207 aRect.setHeight(nTokenValue);
1208 break;
1209 case RTF_DPPOLYCOUNT:
1210 bPolygonActive = true;
1211 break;
1212 case RTF_DPPTX:
1213 aPoint.setX(nTokenValue);
1214 break;
1215 case RTF_DPPTY:
1216 aPoint.setY(nTokenValue);
1217
1218 if(bPolygonActive)
1219 {
1220 aPolygon.append(aPoint);
1221 }
1222
1223 break;
1224 default:
1225 break;
1226 }
1227 }
1228 SkipToken(-1);
1229 /*
1230 const Point aPointC1( 0, 0 );
1231 const Point aPointC2( 100, 200 );
1232 const Point aPointC3( 300, 400 );
1233 XPolygon aPolygonC(3);
1234 aPolygonC[0] = aPointC1;
1235 aPolygonC[1] = aPointC2;
1236 aPolygonC[2] = aPointC3;
1237 */
1238 if(bPolygonActive && aPolygon.count())
1239 {
1240 SdrPathObj* pStroke = new SdrPathObj(OBJ_PLIN, ::basegfx::B2DPolyPolygon(aPolygon));
1241 SfxItemSet aFlySet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1);
1242 SwFmtSurround aSur( SURROUND_PARALLEL );
1243 aSur.SetContour( false );
1244 aSur.SetOutside(true);
1245 aFlySet.Put( aSur );
1246 SwFmtFollowTextFlow aFollowTextFlow( sal_False );
1247 aFlySet.Put( aFollowTextFlow );
1248 /*
1249 sw::util::SetLayer aSetLayer(*pDoc);
1250 aSetLayer.SendObjectToHeaven(*pStroke);
1251 */
1252 SwFmtAnchor aAnchor( FLY_AT_PARA );
1253 aAnchor.SetAnchor( pPam->GetPoint() );
1254 aFlySet.Put( aAnchor );
1255
1256 /*
1257 text::RelOrientation::FRAME, // Absatz inkl. Raender
1258 text::RelOrientation::PRINT_AREA, // Absatz ohne Raender
1259 text::RelOrientation::CHAR, // an einem Zeichen
1260 text::RelOrientation::PAGE_LEFT, // im linken Seitenrand
1261 text::RelOrientation::PAGE_RIGHT, // im rechten Seitenrand
1262 text::RelOrientation::FRAME_LEFT, // im linken Absatzrand
1263 text::RelOrientation::FRAME_RIGHT, // im rechten Absatzrand
1264 text::RelOrientation::PAGE_FRAME, // Seite inkl. Raender, bei seitengeb. identisch mit text::RelOrientation::FRAME
1265 text::RelOrientation::PAGE_PRINT_AREA, // Seite ohne Raender, bei seitengeb. identisch mit text::RelOrientation::PRTAREA
1266 // OD 11.11.2003 #i22341#
1267 text::RelOrientation::TEXT_LINE, // vertical relative to top of text line, only for to-character
1268 // anchored objects.
1269
1270
1271 text::HoriOrientation::NONE, //Der Wert in nYPos gibt die RelPos direkt an.
1272 text::HoriOrientation::RIGHT, //Der Rest ist fuer automatische Ausrichtung.
1273 text::HoriOrientation::CENTER,
1274 text::HoriOrientation::LEFT,
1275 text::HoriOrientation::INSIDE,
1276 text::HoriOrientation::OUTSIDE,
1277 text::HoriOrientation::FULL, //Spezialwert fuer Tabellen
1278 text::HoriOrientation::LEFT_AND_WIDTH //Auch fuer Tabellen
1279 */
1280 SwFmtHoriOrient aHori( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME );
1281 aFlySet.Put( aHori );
1282 /*
1283 text::VertOrientation::NONE, //Der Wert in nYPos gibt die RelPos direkt an.
1284 text::VertOrientation::TOP, //Der Rest ist fuer automatische Ausrichtung.
1285 text::VertOrientation::CENTER,
1286 text::VertOrientation::BOTTOM,
1287 text::VertOrientation::CHAR_TOP, //Ausrichtung _nur_ fuer Zeichengebundene Rahmen
1288 text::VertOrientation::CHAR_CENTER, //wie der Name jew. sagt wird der RefPoint des Rahmens
1289 text::VertOrientation::CHAR_BOTTOM, //entsprechend auf die Oberkante, Mitte oder Unterkante
1290 text::VertOrientation::LINE_TOP, //der Zeile gesetzt. Der Rahmen richtet sich dann
1291 text::VertOrientation::LINE_CENTER, //entsprechend aus.
1292 text::VertOrientation::LINE_BOTTOM
1293 */
1294 SwFmtVertOrient aVert( 0, text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME );
1295 aFlySet.Put( aVert );
1296
1297 pDoc->GetOrCreateDrawModel();
1298 SwDrawModel* pDrawModel = pDoc->GetDrawModel();
1299 SdrPage* pDrawPg = pDrawModel->GetPage(0);
1300 pDrawPg->InsertObject(pStroke, 0);
1301
1302 pStroke->SetSnapRect(aRect);
1303
1304 /* SwFrmFmt* pRetFrmFmt = */pDoc->InsertDrawObj(*pPam, *pStroke, aFlySet );
1305 }
1306 }
1307
InsertShpObject(SdrObject * pStroke,int _nZOrder)1308 void SwRTFParser::InsertShpObject(SdrObject* pStroke, int _nZOrder)
1309 {
1310 SfxItemSet aFlySet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1);
1311 SwFmtSurround aSur( SURROUND_THROUGHT );
1312 aSur.SetContour( false );
1313 aSur.SetOutside(true);
1314 aFlySet.Put( aSur );
1315 SwFmtFollowTextFlow aFollowTextFlow( sal_False );
1316 aFlySet.Put( aFollowTextFlow );
1317
1318 SwFmtAnchor aAnchor( FLY_AT_PARA );
1319 aAnchor.SetAnchor( pPam->GetPoint() );
1320 aFlySet.Put( aAnchor );
1321
1322
1323 SwFmtHoriOrient aHori( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME );
1324 aFlySet.Put( aHori );
1325
1326 SwFmtVertOrient aVert( 0, text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME );
1327 aFlySet.Put( aVert );
1328
1329 aFlySet.Put(SvxOpaqueItem(RES_OPAQUE,false));
1330
1331 pDoc->GetOrCreateDrawModel();
1332 SwDrawModel* pDrawModel = pDoc->GetDrawModel();
1333 SdrPage* pDrawPg = pDrawModel->GetPage(0);
1334 pDrawPg->InsertObject(pStroke);
1335 pDrawPg->SetObjectOrdNum(pStroke->GetOrdNum(), _nZOrder);
1336 /* SwFrmFmt* pRetFrmFmt = */pDoc->InsertDrawObj(*pPam, *pStroke, aFlySet );
1337 }
1338
rotate(const::basegfx::B2DPoint & rStart,const::basegfx::B2DPoint & rEnd)1339 ::basegfx::B2DPoint rotate(const ::basegfx::B2DPoint& rStart, const ::basegfx::B2DPoint& rEnd)
1340 {
1341 const ::basegfx::B2DVector aVector(rStart - rEnd);
1342 return ::basegfx::B2DPoint(aVector.getY() + rEnd.getX(), -aVector.getX() + rEnd.getY());
1343 }
1344
1345
ReadShapeObject()1346 void SwRTFParser::ReadShapeObject()
1347 {
1348 int nToken;
1349 int level;
1350 level=1;
1351 ::basegfx::B2DPoint aPointLeftTop;
1352 ::basegfx::B2DPoint aPointRightBottom;
1353 String sn;
1354 sal_Int32 shapeType=-1;
1355 Graphic aGrf;
1356 bool bGrfValid=false;
1357 bool fFilled=true;
1358 Color fillColor(255, 255, 255);
1359 bool fLine=true;
1360 int lineWidth=9525/360;
1361 String shpTxt;
1362 bool bshpTxt=false;
1363 int txflTextFlow=0;
1364 ::rtl::OUString sDescription, sName;
1365
1366
1367 while (level>0 && IsParserWorking())
1368 {
1369 nToken = GetNextToken();
1370 switch(nToken)
1371 {
1372 case '}':
1373 level--;
1374 break;
1375 case '{':
1376 level++;
1377 break;
1378 case RTF_SHPLEFT:
1379 aPointLeftTop.setX(nTokenValue);
1380 break;
1381 case RTF_SHPTOP:
1382 aPointLeftTop.setY(nTokenValue);
1383 break;
1384 case RTF_SHPBOTTOM:
1385 aPointRightBottom.setY(nTokenValue);
1386 break;
1387 case RTF_SHPRIGHT:
1388 aPointRightBottom.setX(nTokenValue);
1389 break;
1390 case RTF_SN:
1391 nToken = GetNextToken();
1392 ASSERT(nToken==RTF_TEXTTOKEN, "expected name");
1393 sn=aToken;
1394 break;
1395 case RTF_SV:
1396 nToken = GetNextToken();
1397 if (nToken==RTF_TEXTTOKEN)
1398 {
1399 if (sn.EqualsAscii("shapeType"))
1400 {
1401 shapeType=aToken.ToInt32();
1402
1403 } else if (sn.EqualsAscii("fFilled"))
1404 {
1405 fFilled=aToken.ToInt32();
1406
1407 } else if (sn.EqualsAscii("fLine"))
1408 {
1409 fLine=aToken.ToInt32();
1410 } else if (sn.EqualsAscii("lineWidth"))
1411 {
1412 lineWidth=aToken.ToInt32()/360;
1413
1414 } else if (sn.EqualsAscii("fillColor"))
1415 {
1416 sal_uInt32 nColor=aToken.ToInt32();
1417 fillColor=Color( (sal_uInt8)nColor, (sal_uInt8)( nColor >> 8 ), (sal_uInt8)( nColor >> 16 ) );
1418 }else if (sn.EqualsAscii("txflTextFlow"))
1419 {
1420 txflTextFlow=aToken.ToInt32();
1421 }
1422 else if (sn.EqualsAscii("wzDescription"))
1423 {
1424 sDescription = aToken;
1425 }
1426 else if(sn.EqualsAscii("wzName"))
1427 {
1428 sName = aToken;
1429 }
1430 }
1431 break;
1432 case RTF_PICT:
1433 {
1434 SvxRTFPictureType aPicType;
1435 bGrfValid=ReadBmpData( aGrf, aPicType );
1436 }
1437 break;
1438 case RTF_SHPRSLT:
1439 if (shapeType!=1 && shapeType!=20 && shapeType!=75)
1440 {
1441 ReadShpRslt();
1442 }
1443 break;
1444 case RTF_SHPTXT:
1445 ReadShpTxt(shpTxt);
1446 bshpTxt=true;
1447 break;
1448
1449 default:
1450 break;
1451 }
1452 }
1453 SkipToken(-1);
1454
1455 SdrObject* pSdrObject = 0;
1456 switch(shapeType)
1457 {
1458 case 202: /* Text Box */
1459 case 1: /* Rectangle */
1460 {
1461 ::basegfx::B2DRange aRange(aPointLeftTop);
1462 aRange.expand(aPointRightBottom);
1463
1464 if (txflTextFlow==2) {
1465 const ::basegfx::B2DPoint a(rotate(aRange.getMinimum(), aRange.getCenter()));
1466 const ::basegfx::B2DPoint b(rotate(aRange.getMaximum(), aRange.getCenter()));
1467
1468 aRange.reset();
1469 aRange.expand(a);
1470 aRange.expand(b);
1471 }
1472
1473 const Rectangle aRect(FRound(aRange.getMinX()), FRound(aRange.getMinY()), FRound(aRange.getMaxX()), FRound(aRange.getMaxY()));
1474 SdrRectObj* pStroke = new SdrRectObj(aRect);
1475 pSdrObject = pStroke;
1476 pStroke->SetSnapRect(aRect);
1477 pDoc->GetOrCreateDrawModel(); // create model
1478 InsertShpObject(pStroke, this->nZOrder++);
1479 SfxItemSet aSet(pStroke->GetMergedItemSet());
1480 if (fFilled)
1481 {
1482 aSet.Put(XFillStyleItem(XFILL_SOLID));
1483 aSet.Put(XFillColorItem( String(), fillColor ) );
1484 }
1485 else
1486 {
1487 aSet.Put(XFillStyleItem(XFILL_NONE));
1488 }
1489 if (!fLine) {
1490 aSet.Put(XLineStyleItem(XLINE_NONE));
1491 } else {
1492 aSet.Put( XLineWidthItem( lineWidth/2 ) ); // lineWidth are in 1000th mm, seems that XLineWidthItem expects 1/2 the line width
1493 }
1494
1495 pStroke->SetMergedItemSet(aSet);
1496 if (bshpTxt) {
1497 SdrOutliner& rOutliner=pDoc->GetDrawModel()->GetDrawOutliner(pStroke);
1498 rOutliner.Clear();
1499 ByteString bs(shpTxt, RTL_TEXTENCODING_ASCII_US);
1500 SvMemoryStream aStream((sal_Char*)bs.GetBuffer(), bs.Len(), STREAM_READ);
1501 rOutliner.Read(aStream, String::CreateFromAscii(""), EE_FORMAT_RTF);
1502 OutlinerParaObject* pParaObject=rOutliner.CreateParaObject();
1503 pStroke->NbcSetOutlinerParaObject(pParaObject);
1504 //delete pParaObject;
1505 rOutliner.Clear();
1506 }
1507 if (txflTextFlow==2) {
1508 long nAngle = 90;
1509 double a = nAngle*100*nPi180;
1510 pStroke->Rotate(pStroke->GetCurrentBoundRect().Center(), nAngle*100, sin(a), cos(a) );
1511
1512 }
1513
1514 }
1515 break;
1516 case 20: /* Line */
1517 {
1518 ::basegfx::B2DPolygon aLine;
1519 aLine.append(aPointLeftTop);
1520 aLine.append(aPointRightBottom);
1521
1522 SdrPathObj* pStroke = new SdrPathObj(OBJ_PLIN, ::basegfx::B2DPolyPolygon(aLine));
1523 pSdrObject = pStroke;
1524 //pStroke->SetSnapRect(aRect);
1525
1526 InsertShpObject(pStroke, this->nZOrder++);
1527 SfxItemSet aSet(pStroke->GetMergedItemSet());
1528 if (!fLine) {
1529 aSet.Put(XLineStyleItem(XLINE_NONE));
1530 } else {
1531 aSet.Put( XLineWidthItem( lineWidth/2 ) ); // lineWidth are in 1000th mm, seems that XLineWidthItem expects 1/2 the line width
1532 }
1533
1534 pStroke->SetMergedItemSet(aSet);
1535 }
1536 break;
1537 case 75 : /* Picture */
1538 if (bGrfValid) {
1539 ::basegfx::B2DRange aRange(aPointLeftTop);
1540 aRange.expand(aPointRightBottom);
1541 const Rectangle aRect(FRound(aRange.getMinX()), FRound(aRange.getMinY()), FRound(aRange.getMaxX()), FRound(aRange.getMaxY()));
1542
1543 SdrRectObj* pStroke = new SdrGrafObj(aGrf);
1544 pSdrObject = pStroke;
1545 pStroke->SetSnapRect(aRect);
1546
1547 InsertShpObject(pStroke, this->nZOrder++);
1548 }
1549 }
1550 if( pSdrObject )
1551 {
1552 pSdrObject->SetDescription(sDescription);
1553 pSdrObject->SetTitle(sName);
1554 }
1555 }
1556
1557 extern void sw3io_ConvertFromOldField( SwDoc& rDoc, sal_uInt16& rWhich,
1558 sal_uInt16& rSubType, sal_uLong &rFmt,
1559 sal_uInt16 nVersion );
1560
ReadRevTbl()1561 sal_uInt16 SwRTFParser::ReadRevTbl()
1562 {
1563 // rStr.Erase( 0 );
1564 int nNumOpenBrakets = 1, nToken; // die erste wurde schon vorher erkannt !!
1565 sal_uInt16 nAuthorTableIndex = 0;
1566
1567 while( nNumOpenBrakets && IsParserWorking() )
1568 {
1569 switch( nToken = GetNextToken() )
1570 {
1571 case '}': --nNumOpenBrakets; break;
1572 case '{':
1573 {
1574 if( RTF_IGNOREFLAG != GetNextToken() )
1575 nToken = SkipToken( -1 );
1576 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
1577 nToken = SkipToken( -2 );
1578 else
1579 {
1580 ReadUnknownData();
1581 nToken = GetNextToken();
1582 if( '}' != nToken )
1583 eState = SVPAR_ERROR;
1584 break;
1585 }
1586 ++nNumOpenBrakets;
1587 }
1588 break;
1589
1590 case RTF_TEXTTOKEN:
1591 aToken.EraseTrailingChars(';');
1592
1593 sal_uInt16 nSWId = pDoc->InsertRedlineAuthor(aToken);
1594 // Store matchpair
1595 if( !pAuthorInfos )
1596 pAuthorInfos = new sw::util::AuthorInfos;
1597 sw::util::AuthorInfo* pAutorInfo = new sw::util::AuthorInfo( nAuthorTableIndex, nSWId );
1598 if( 0 == pAuthorInfos->Insert( pAutorInfo ) )
1599 delete pAutorInfo;
1600
1601 aRevTbl.push_back(aToken);
1602 nAuthorTableIndex++;
1603 break;
1604 }
1605 }
1606 SkipToken( -1 );
1607 return nAuthorTableIndex;
1608 }
1609
NextToken(int nToken)1610 void SwRTFParser::NextToken( int nToken )
1611 {
1612 sal_uInt16 eDateFmt;
1613
1614 switch( nToken )
1615 {
1616 case RTF_FOOTNOTE:
1617 {
1618 //We can only insert a footnote if we're not inside a footnote. e.g.
1619 //#i7713#
1620
1621 // in insert mode it's also possible to be inside of a footnote!
1622 bool bInsertIntoFootnote = false;
1623 if( !IsNewDoc() )
1624 {
1625 SwStartNode* pSttNode = pPam->GetNode()->StartOfSectionNode();
1626 while(pSttNode && pSttNode->IsSectionNode())
1627 {
1628 pSttNode = pSttNode->StartOfSectionNode();
1629 }
1630 if( SwFootnoteStartNode == pSttNode->GetStartNodeType() )
1631 bInsertIntoFootnote = true;
1632 }
1633 if (!mbIsFootnote && !bInsertIntoFootnote)
1634 {
1635 ReadHeaderFooter( nToken );
1636 SkipToken( -1 ); // Klammer wieder zurueck
1637 }
1638 }
1639 break;
1640 case RTF_SWG_PRTDATA:
1641 ReadPrtData();
1642 break;
1643 case RTF_XE:
1644 ReadXEField();
1645 break;
1646 case RTF_FIELD:
1647 ReadField();
1648 break;
1649 case RTF_SHPRSLT:
1650 ReadShpRslt();
1651 break;
1652 case RTF_DO:
1653 ReadDrawingObject();
1654 break;
1655 case RTF_SHP:
1656 ReadShapeObject();
1657 break;
1658 case RTF_SHPPICT:
1659 case RTF_PICT:
1660 ReadBitmapData();
1661 break;
1662 #ifdef READ_OLE_OBJECT
1663 case RTF_OBJECT:
1664 ReadOLEData();
1665 break;
1666 #endif
1667 case RTF_TROWD: ReadTable( nToken ); break;
1668 case RTF_PGDSCTBL:
1669 if( !IsNewDoc() )
1670 SkipPageDescTbl();
1671 else
1672 ReadPageDescTbl();
1673 break;
1674 case RTF_LISTTABLE: ReadListTable(); break;
1675 case RTF_LISTOVERRIDETABLE: ReadListOverrideTable(); break;
1676
1677 case RTF_LISTTEXT:
1678 GetAttrSet().Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 ));
1679 SkipGroup();
1680 break;
1681
1682 case RTF_PN:
1683 if( bNewNumList )
1684 SkipGroup();
1685 else
1686 {
1687 bStyleTabValid = sal_True;
1688 if (SwNumRule* pRule = ReadNumSecLevel( nToken ))
1689 {
1690 GetAttrSet().Put( SwNumRuleItem( pRule->GetName() ));
1691
1692 if( SFX_ITEM_SET != GetAttrSet().GetItemState( FN_PARAM_NUM_LEVEL, sal_False ))
1693 GetAttrSet().Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 ));
1694 }
1695 }
1696 break;
1697
1698
1699 case RTF_BKMKSTART:
1700 if(RTF_TEXTTOKEN == GetNextToken())
1701 mpBookmarkStart = new BookmarkPosition(*pPam);
1702 else
1703 SkipToken(-1);
1704
1705 SkipGroup();
1706 break;
1707
1708 case RTF_BKMKEND:
1709 if(RTF_TEXTTOKEN == GetNextToken())
1710 {
1711 const String& sBookmark = aToken;
1712 KeyCode aEmptyKeyCode;
1713 if (mpBookmarkStart)
1714 {
1715 BookmarkPosition aBookmarkEnd(*pPam);
1716 SwPaM aBookmarkRegion( mpBookmarkStart->maMkNode, mpBookmarkStart->mnMkCntnt,
1717 aBookmarkEnd.maMkNode, aBookmarkEnd.mnMkCntnt);
1718 if (*mpBookmarkStart == aBookmarkEnd)
1719 aBookmarkRegion.DeleteMark();
1720 pDoc->getIDocumentMarkAccess()->makeMark(aBookmarkRegion, sBookmark, IDocumentMarkAccess::BOOKMARK);
1721 }
1722 delete mpBookmarkStart, mpBookmarkStart = 0;
1723 }
1724 else
1725 SkipToken(-1);
1726
1727 SkipGroup();
1728 break;
1729
1730
1731 case RTF_PNSECLVL:{
1732 if( bNewNumList)
1733 SkipGroup();
1734 else
1735 ReadNumSecLevel( nToken );
1736 break;
1737 }
1738
1739 case RTF_PNTEXT:
1740 case RTF_NONSHPPICT:
1741 SkipGroup();
1742 break;
1743
1744 case RTF_DEFFORMAT:
1745 case RTF_DEFTAB:
1746 case RTF_DEFLANG:
1747 // sind zwar Dok-Controls, werden aber manchmal auch vor der
1748 // Font/Style/Color-Tabelle gesetzt!
1749 SvxRTFParser::NextToken( nToken );
1750 break;
1751
1752 case RTF_PAGE:
1753 if (pTableNode==NULL) { //#117410#: A \page command within a table is ignored by Word.
1754 if (lcl_UsedPara(*pPam))
1755 InsertPara();
1756 CheckInsNewTblLine();
1757 pDoc->InsertPoolItem(*pPam,
1758 SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK), 0);
1759 }
1760 break;
1761
1762 case RTF_SECT:
1763 ReadSectControls( nToken );
1764 break;
1765 case RTF_CELL:
1766 // --> OD 2008-12-22 #i83368#
1767 mbReadCellWhileReadSwFly = bReadSwFly;
1768 // <--
1769 if (CantUseTables())
1770 InsertPara();
1771 else
1772 {
1773 // Tabelle nicht mehr vorhanden ?
1774 if (USHRT_MAX != nInsTblRow && !pTableNode)
1775 NewTblLine(); // evt. Line copieren
1776 GotoNextBox();
1777 }
1778 break;
1779
1780 case RTF_ROW:
1781 bTrowdRead=false;
1782 if (!CantUseTables())
1783 {
1784 // aus der Line raus
1785 m_nCurrentBox = 0;
1786 pTableNode = 0;
1787 // noch in der Tabelle drin?
1788 SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
1789 const SwTableNode* pTblNd = rIdx.GetNode().FindTableNode();
1790 if( pTblNd )
1791 {
1792 // search the end of this row
1793 const SwStartNode* pBoxStt =
1794 rIdx.GetNode().FindTableBoxStartNode();
1795 const SwTableBox* pBox = pTblNd->GetTable().GetTblBox(
1796 pBoxStt->GetIndex() );
1797 const SwTableLine* pLn = pBox->GetUpper();
1798 pBox = pLn->GetTabBoxes()[ pLn->GetTabBoxes().Count() - 1 ];
1799 rIdx = *pBox->GetSttNd()->EndOfSectionNode();
1800 pPam->Move( fnMoveForward, fnGoNode );
1801 }
1802 nInsTblRow = static_cast< sal_uInt16 >(GetOpenBrakets());
1803 SetPardTokenRead( sal_False );
1804 SwPaM aTmp(*pPam);
1805 aTmp.Move( fnMoveBackward, fnGoNode );
1806 }
1807 ::SetProgressState( rInput.Tell(), pDoc->GetDocShell() );
1808 break;
1809
1810 case RTF_INTBL:
1811 if (!CantUseTables())
1812 {
1813 if( !pTableNode ) // Tabelle nicht mehr vorhanden ?
1814 {
1815 if (RTF_TROWD != GetNextToken())
1816 NewTblLine(); // evt. Line copieren
1817 SkipToken(-1);
1818 }
1819 else
1820 {
1821 // Crsr nicht mehr in der Tabelle ?
1822 if( !pPam->GetNode()->FindTableNode() )
1823 {
1824 // dann wieder in die letzte Box setzen
1825 // (kann durch einlesen von Flys geschehen!)
1826 pPam->GetPoint()->nNode = *pTableNode->EndOfSectionNode();
1827 pPam->Move( fnMoveBackward );
1828 }
1829 }
1830 }
1831 break;
1832
1833 case RTF_REVTBL:
1834 ReadRevTbl();
1835 break;
1836
1837 case RTF_REVISED:
1838 pRedlineInsert = new SwFltRedline(nsRedlineType_t::REDLINE_INSERT, 0, DateTime(Date( 0 ), Time( 0 )));
1839 break;
1840
1841 case RTF_DELETED:
1842 pRedlineDelete = new SwFltRedline(nsRedlineType_t::REDLINE_DELETE, 0, DateTime(Date( 0 ), Time( 0 )));
1843 break;
1844
1845 case RTF_REVAUTH:
1846 {
1847 sw::util::AuthorInfo aEntry( static_cast< sal_uInt16 >(nTokenValue) );
1848 sal_uInt16 nPos;
1849
1850 if(pRedlineInsert)
1851 {
1852 if (pAuthorInfos && pAuthorInfos->Seek_Entry(&aEntry, &nPos))
1853 {
1854 if (const sw::util::AuthorInfo* pAuthor = pAuthorInfos->GetObject(nPos))
1855 {
1856 pRedlineInsert->nAutorNo = pAuthor->nOurId;
1857 }
1858 }
1859 }
1860 }
1861 break;
1862
1863 case RTF_REVAUTHDEL:
1864 {
1865 sw::util::AuthorInfo aEntry( static_cast< short >(nTokenValue) );
1866 sal_uInt16 nPos;
1867
1868 if(pRedlineDelete)
1869 {
1870 if (pAuthorInfos && pAuthorInfos->Seek_Entry(&aEntry, &nPos))
1871 {
1872 if (const sw::util::AuthorInfo* pAuthor = pAuthorInfos->GetObject(nPos))
1873 {
1874 pRedlineDelete->nAutorNo = pAuthor->nOurId;
1875 }
1876 }
1877 }
1878 }
1879 break;
1880
1881 case RTF_REVDTTM:
1882 if (pRedlineInsert != NULL)
1883 pRedlineInsert->aStamp = sw::ms::DTTM2DateTime(nTokenValue);
1884
1885 break;
1886
1887 case RTF_REVDTTMDEL:
1888 pRedlineDelete->aStamp = sw::ms::DTTM2DateTime(nTokenValue);
1889 break;
1890
1891
1892 case RTF_FLY_INPARA:
1893 // \pard und plain ueberlesen !
1894 if( '}' != GetNextToken() && '}' != GetNextToken() )
1895 {
1896 // Zeichengebundener Fly in Fly
1897 ReadHeaderFooter( nToken );
1898 SetPardTokenRead( sal_False );
1899 }
1900 break;
1901
1902 case RTF_PGDSCNO:
1903 if( IsNewDoc() && bSwPageDesc &&
1904 sal_uInt16(nTokenValue) < pDoc->GetPageDescCnt() )
1905 {
1906 const SwPageDesc* pPgDsc =
1907 &const_cast<const SwDoc *>(pDoc)
1908 ->GetPageDesc( sal_uInt16(nTokenValue) );
1909 CheckInsNewTblLine();
1910 pDoc->InsertPoolItem(*pPam, SwFmtPageDesc( pPgDsc ), 0);
1911 }
1912 break;
1913
1914 case RTF_COLUM:
1915 pDoc->InsertPoolItem(*pPam,
1916 SvxFmtBreakItem( SVX_BREAK_COLUMN_BEFORE, RES_BREAK ), 0);
1917 break;
1918
1919 case RTF_DXFRTEXT: // werden nur im Zusammenhang mit Flys ausgewertet
1920 case RTF_DFRMTXTX:
1921 case RTF_DFRMTXTY:
1922 break;
1923
1924 case RTF_CHDATE: eDateFmt = DF_SHORT; goto SETCHDATEFIELD;
1925 case RTF_CHDATEA: eDateFmt = DF_SSYS; goto SETCHDATEFIELD;
1926 case RTF_CHDATEL: eDateFmt = DF_LSYS; goto SETCHDATEFIELD;
1927 SETCHDATEFIELD:
1928 {
1929 sal_uInt16 nSubType = DATEFLD, nWhich = RES_DATEFLD;
1930 sal_uLong nFormat = eDateFmt;
1931 sw3io_ConvertFromOldField( *pDoc, nWhich, nSubType, nFormat, 0x0110 );
1932
1933 SwDateTimeField aDateFld( (SwDateTimeFieldType*)
1934 pDoc->GetSysFldType( RES_DATETIMEFLD ), DATEFLD, nFormat);
1935 CheckInsNewTblLine();
1936 pDoc->InsertPoolItem(*pPam, SwFmtFld( aDateFld ), 0);
1937 }
1938 break;
1939
1940 case RTF_CHTIME:
1941 {
1942 sal_uInt16 nSubType = TIMEFLD, nWhich = RES_TIMEFLD;
1943 sal_uLong nFormat = TF_SSMM_24;
1944 sw3io_ConvertFromOldField( *pDoc, nWhich, nSubType, nFormat, 0x0110 );
1945 SwDateTimeField aTimeFld( (SwDateTimeFieldType*)
1946 pDoc->GetSysFldType( RES_DATETIMEFLD ), TIMEFLD, nFormat);
1947 CheckInsNewTblLine();
1948 pDoc->InsertPoolItem(*pPam, SwFmtFld( aTimeFld ), 0);
1949 }
1950 break;
1951
1952 case RTF_CHPGN:
1953 {
1954 SwPageNumberField aPageFld( (SwPageNumberFieldType*)
1955 pDoc->GetSysFldType( RES_PAGENUMBERFLD ),
1956 PG_RANDOM, SVX_NUM_ARABIC );
1957 CheckInsNewTblLine();
1958 pDoc->InsertPoolItem(*pPam, SwFmtFld(aPageFld), 0);
1959 }
1960 break;
1961
1962 case RTF_CHFTN:
1963 bFootnoteAutoNum = sal_True;
1964 break;
1965
1966 case RTF_NOFPAGES:
1967 if( IsNewDoc() && nTokenValue && -1 != nTokenValue )
1968 ((SwDocStat&)pDoc->GetDocStat()).nPage = (sal_uInt16)nTokenValue;
1969 break;
1970
1971 case RTF_NOFWORDS:
1972 if( IsNewDoc() && nTokenValue && -1 != nTokenValue )
1973 ((SwDocStat&)pDoc->GetDocStat()).nWord = (sal_uInt16)nTokenValue;
1974 break;
1975 case RTF_NOFCHARS:
1976 if( IsNewDoc() && nTokenValue && -1 != nTokenValue )
1977 ((SwDocStat&)pDoc->GetDocStat()).nChar = (sal_uInt16)nTokenValue;
1978 break;
1979 case RTF_LYTPRTMET:
1980 if (IsNewDoc())
1981 pDoc->set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, false);
1982 break;
1983 case RTF_U:
1984 {
1985 CheckInsNewTblLine();
1986 if( nTokenValue )
1987 aToken = (sal_Unicode )nTokenValue;
1988 pDoc->InsertString( *pPam, aToken );
1989 }
1990 break;
1991
1992 case RTF_USERPROPS:
1993 ReadUserProperties(); // #i28758 For now we don't support user properties
1994 break;
1995
1996 // RTF_SUBENTRYINDEX
1997
1998 default:
1999 switch( nToken & ~(0xff | RTF_SWGDEFS) )
2000 {
2001 case RTF_DOCFMT:
2002 ReadDocControls( nToken );
2003 break;
2004 case RTF_SECTFMT:
2005 ReadSectControls( nToken );
2006 break;
2007 case RTF_APOCTL:
2008 if (nReadFlyDepth < 10)
2009 {
2010 nReadFlyDepth++;
2011 ReadFly( nToken );
2012 nReadFlyDepth--;
2013 }
2014 break;
2015
2016 case RTF_BRDRDEF | RTF_TABLEDEF:
2017 case RTF_SHADINGDEF | RTF_TABLEDEF:
2018 case RTF_TABLEDEF:
2019 ReadTable( nToken );
2020 break;
2021
2022 case RTF_INFO:
2023 ReadInfo();
2024 break;
2025
2026 default:
2027 if( USHRT_MAX != nInsTblRow &&
2028 (nInsTblRow > GetOpenBrakets() || IsPardTokenRead() ))
2029 nInsTblRow = USHRT_MAX;
2030
2031 SvxRTFParser::NextToken( nToken );
2032 break;
2033 }
2034 }
2035 if( USHRT_MAX != nInsTblRow &&
2036 (nInsTblRow > GetOpenBrakets() || IsPardTokenRead() ))
2037 nInsTblRow = USHRT_MAX;
2038 }
2039
2040
2041
InsertText()2042 void SwRTFParser::InsertText()
2043 {
2044 bContainsPara = false;
2045 // dann fuege den String ein, ohne das Attribute am Ende
2046 // aufgespannt werden.
2047 CheckInsNewTblLine();
2048
2049 if(pRedlineInsert)
2050 mpRedlineStack->open(*pPam->GetPoint(), *pRedlineInsert);
2051 if(pRedlineDelete)
2052 mpRedlineStack->open(*pPam->GetPoint(), *pRedlineDelete);
2053
2054 pDoc->InsertString( *pPam, aToken );
2055
2056 if(pRedlineDelete)
2057 {
2058 mpRedlineStack->close(*pPam->GetPoint(), pRedlineDelete->eType);
2059 }
2060
2061 if(pRedlineInsert)
2062 {
2063 mpRedlineStack->close(*pPam->GetPoint(), pRedlineInsert->eType);
2064 }
2065
2066
2067 }
2068
2069
InsertPara()2070 void SwRTFParser::InsertPara()
2071 {
2072 bContainsPara = true;
2073 CheckInsNewTblLine();
2074 pDoc->AppendTxtNode(*pPam->GetPoint());
2075
2076 // setze das default Style
2077 if( !bStyleTabValid )
2078 MakeStyleTab();
2079
2080 SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 );
2081 if( !pColl )
2082 pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
2083 pDoc->SetTxtFmtColl( *pPam, pColl );
2084
2085 ::SetProgressState( rInput.Tell(), pDoc->GetDocShell() );
2086 }
2087
2088
2089
MovePos(int bForward)2090 void SwRTFParser::MovePos( int bForward )
2091 {
2092 if( bForward )
2093 pPam->Move( fnMoveForward );
2094 else
2095 pPam->Move( fnMoveBackward );
2096 }
2097
IsEndPara(SvxNodeIdx * pNd,xub_StrLen nCnt) const2098 int SwRTFParser::IsEndPara( SvxNodeIdx* pNd, xub_StrLen nCnt ) const
2099 {
2100 SwCntntNode *pNode = pDoc->GetNodes()[pNd->GetIdx()]->GetCntntNode();
2101 return pNode && pNode->Len() == nCnt;
2102 }
2103
UncompressableStackEntry(const SvxRTFItemStackType & rSet) const2104 bool SwRTFParser::UncompressableStackEntry(const SvxRTFItemStackType &rSet)
2105 const
2106 {
2107 /*
2108 #i21961#
2109 Seeing as CHARFMT sets all the properties of the charfmt itself, its not
2110 good enough to just see it as a single property from the point of
2111 compressing property sets. If bold and charfmt are in a child, and bold is
2112 in the parent, removing bold from the child will not result in the same
2113 thing, if the charfmt removes bold itself for example
2114 */
2115 bool bRet = false;
2116 if (rSet.GetAttrSet().Count())
2117 {
2118
2119 if (SFX_ITEM_SET ==
2120 rSet.GetAttrSet().GetItemState(RES_TXTATR_CHARFMT, sal_False))
2121 {
2122 bRet = true;
2123 }
2124 }
2125 return bRet;
2126 }
2127
SetEndPrevPara(SvxNodeIdx * & rpNodePos,xub_StrLen & rCntPos)2128 void SwRTFParser::SetEndPrevPara( SvxNodeIdx*& rpNodePos, xub_StrLen& rCntPos )
2129 {
2130 SwNodeIndex aIdx( pPam->GetPoint()->nNode );
2131 SwCntntNode* pNode = pDoc->GetNodes().GoPrevious( &aIdx );
2132 if( !pNode )
2133 {
2134 ASSERT( sal_False, "keinen vorherigen ContentNode gefunden" );
2135 }
2136
2137 rpNodePos = new SwNodeIdx( aIdx );
2138 rCntPos = pNode->Len();
2139 }
2140
SetAttrInDoc(SvxRTFItemStackType & rSet)2141 void SwRTFParser::SetAttrInDoc( SvxRTFItemStackType &rSet )
2142 {
2143 sal_uLong nSNd = rSet.GetSttNodeIdx(), nENd = rSet.GetEndNodeIdx();
2144 xub_StrLen nSCnt = rSet.GetSttCnt(), nECnt = rSet.GetEndCnt();
2145
2146 SwPaM aPam( *pPam->GetPoint() );
2147
2148 #ifdef DBG_UTIL
2149 ASSERT( nSNd <= nENd, "Start groesser als Ende" );
2150 SwNode* pDebugNd = pDoc->GetNodes()[ nSNd ];
2151 ASSERT( pDebugNd->IsCntntNode(), "Start kein ContentNode" );
2152 pDebugNd = pDoc->GetNodes()[ nENd ];
2153 ASSERT( pDebugNd->IsCntntNode(), "Ende kein ContentNode" );
2154 #endif
2155
2156 SwCntntNode* pCNd = pDoc->GetNodes()[ nSNd ]->GetCntntNode();
2157 aPam.GetPoint()->nNode = nSNd;
2158 aPam.GetPoint()->nContent.Assign( pCNd, nSCnt );
2159 aPam.SetMark();
2160 if( nENd == nSNd )
2161 aPam.GetPoint()->nContent = nECnt;
2162 else
2163 {
2164 aPam.GetPoint()->nNode = nENd;
2165 pCNd = aPam.GetCntntNode();
2166 aPam.GetPoint()->nContent.Assign( pCNd, nECnt );
2167 }
2168
2169 // setze ueber den Bereich das entsprechende Style
2170 if( rSet.StyleNo() )
2171 {
2172 // setze jetzt das Style
2173 if( !bStyleTabValid )
2174 MakeStyleTab();
2175 SwTxtFmtColl* pColl = aTxtCollTbl.Get( rSet.StyleNo() );
2176 if( pColl )
2177 pDoc->SetTxtFmtColl( aPam, pColl, false );
2178 }
2179
2180 const SfxPoolItem* pItem;
2181 const SfxPoolItem* pCharFmt;
2182 if (rSet.GetAttrSet().Count() )
2183 {
2184
2185 // falls eine Zeichenvorlage im Set steht, deren Attribute
2186 // aus dem Set loeschen. Sonst sind diese doppelt, was man ja
2187 // nicht will.
2188 if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(
2189 RES_TXTATR_CHARFMT, sal_False, &pCharFmt ) &&
2190 ((SwFmtCharFmt*)pCharFmt)->GetCharFmt() )
2191 {
2192 const String& rName = ((SwFmtCharFmt*)pCharFmt)->GetCharFmt()->GetName();
2193 SvxRTFStyleType* pStyle = GetStyleTbl().First();
2194 do {
2195 if( pStyle->bIsCharFmt && pStyle->sName == rName )
2196 {
2197 // alle Attribute, die schon vom Style definiert sind, aus dem
2198 // akt. AttrSet entfernen
2199 SfxItemSet &rAttrSet = rSet.GetAttrSet(),
2200 &rStyleSet = pStyle->aAttrSet;
2201 SfxItemIter aIter( rAttrSet );
2202 sal_uInt16 nWhich = aIter.GetCurItem()->Which();
2203 while( sal_True )
2204 {
2205 const SfxPoolItem* pI;
2206 if( SFX_ITEM_SET == rStyleSet.GetItemState(
2207 nWhich, sal_False, &pI ) && *pI == *aIter.GetCurItem())
2208 rAttrSet.ClearItem( nWhich ); // loeschen
2209
2210 if( aIter.IsAtEnd() )
2211 break;
2212 nWhich = aIter.NextItem()->Which();
2213 }
2214 break;
2215 }
2216 } while( 0 != (pStyle = GetStyleTbl().Next()) );
2217
2218 pDoc->InsertPoolItem(aPam, *pCharFmt, 0);
2219 rSet.GetAttrSet().ClearItem(RES_TXTATR_CHARFMT); //test hack
2220 }
2221 if (rSet.GetAttrSet().Count())
2222 {
2223 // dann setze ueber diesen Bereich die Attrbiute
2224 SetSwgValues(rSet.GetAttrSet());
2225 pDoc->InsertItemSet(aPam, rSet.GetAttrSet(),
2226 nsSetAttrMode::SETATTR_DONTCHGNUMRULE);
2227 }
2228 }
2229
2230 if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(
2231 FN_PARAM_NUM_LEVEL, sal_False, &pItem ))
2232 {
2233 // dann ueber den Bereich an den Nodes das NodeNum setzen
2234 for( sal_uLong n = nSNd; n <= nENd; ++n )
2235 {
2236 SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode();
2237 if( pTxtNd )
2238 {
2239 pTxtNd->SetAttrListLevel((sal_uInt8) ((SfxUInt16Item*)pItem)->GetValue());
2240 // Update vom LR-Space abschalten?
2241 }
2242 }
2243 }
2244
2245 if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(
2246 RES_PARATR_NUMRULE, sal_False, &pItem ))
2247 {
2248 const SwNumRule* pRule = pDoc->FindNumRulePtr(
2249 ((SwNumRuleItem*)pItem)->GetValue() );
2250 if( pRule && ( pRule->IsContinusNum() || !bNewNumList ))
2251 {
2252 // diese Rule hat keinen Level, also muss die Einrueckung
2253 // erhalten bleiben!
2254 // dann ueber den Bereich an den Nodes das Flag zuruecksetzen
2255 for( sal_uLong n = nSNd; n <= nENd; ++n )
2256 {
2257 SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode();
2258 if( pTxtNd )
2259 {
2260 // Update vom LR-Space abschalten
2261 pTxtNd->SetNumLSpace( sal_False );
2262 }
2263 }
2264 }
2265 }
2266
2267 bool bNoNum = true;
2268 if (
2269 (SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(RES_PARATR_NUMRULE))
2270 || (SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(FN_PARAM_NUM_LEVEL))
2271 )
2272 {
2273 bNoNum = false;
2274 }
2275
2276 if (bNoNum)
2277 {
2278 for( sal_uLong n = nSNd; n <= nENd; ++n )
2279 {
2280 SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode();
2281 if( pTxtNd )
2282 {
2283 pTxtNd->SetAttr( *GetDfltAttr(RES_PARATR_NUMRULE) );
2284 // reset all list attributes
2285 pTxtNd->ResetAttr( RES_PARATR_LIST_LEVEL );
2286 pTxtNd->ResetAttr( RES_PARATR_LIST_ISRESTART );
2287 pTxtNd->ResetAttr( RES_PARATR_LIST_RESTARTVALUE );
2288 pTxtNd->ResetAttr( RES_PARATR_LIST_ISCOUNTED );
2289 pTxtNd->ResetAttr( RES_PARATR_LIST_ID );
2290 }
2291 }
2292 }
2293 }
2294
DocPageInformation()2295 DocPageInformation::DocPageInformation()
2296 : maBox( RES_BOX ),
2297 mnPaperw(12240), mnPaperh(15840), mnMargl(1800), mnMargr(1800),
2298 mnMargt(1440), mnMargb(1440), mnGutter(0), mnPgnStart(1), mbFacingp(false),
2299 mbLandscape(false), mbRTLdoc(false)
2300 {
2301 }
2302
SectPageInformation(const DocPageInformation & rDoc)2303 SectPageInformation::SectPageInformation(const DocPageInformation &rDoc)
2304 : maBox(rDoc.maBox), mpTitlePageHdFt(0), mpPageHdFt(0),
2305 mnPgwsxn(rDoc.mnPaperw), mnPghsxn(rDoc.mnPaperh), mnMarglsxn(rDoc.mnMargl),
2306 mnMargrsxn(rDoc.mnMargr), mnMargtsxn(rDoc.mnMargt),
2307 mnMargbsxn(rDoc.mnMargb), mnGutterxsn(rDoc.mnGutter), mnHeadery(720),
2308 mnFootery(720), mnPgnStarts(rDoc.mnPgnStart), mnCols(1), mnColsx(720),
2309 mnStextflow(rDoc.mbRTLdoc ? 3 : 0), mnBkc(2), mbLndscpsxn(rDoc.mbLandscape),
2310 mbTitlepg(false), mbFacpgsxn(rDoc.mbFacingp), mbRTLsection(rDoc.mbRTLdoc),
2311 mbPgnrestart(false), mbTitlePageHdFtUsed(false), mbPageHdFtUsed(false)
2312 {
2313 };
2314
SectPageInformation(const SectPageInformation & rSect)2315 SectPageInformation::SectPageInformation(const SectPageInformation &rSect)
2316 : maColumns(rSect.maColumns), maBox(rSect.maBox),
2317 maNumType(rSect.maNumType), mpTitlePageHdFt(rSect.mpTitlePageHdFt),
2318 mpPageHdFt(rSect.mpPageHdFt), mnPgwsxn(rSect.mnPgwsxn),
2319 mnPghsxn(rSect.mnPghsxn), mnMarglsxn(rSect.mnMarglsxn),
2320 mnMargrsxn(rSect.mnMargrsxn), mnMargtsxn(rSect.mnMargtsxn),
2321 mnMargbsxn(rSect.mnMargbsxn), mnGutterxsn(rSect.mnGutterxsn),
2322 mnHeadery(rSect.mnHeadery), mnFootery(rSect.mnFootery),
2323 mnPgnStarts(rSect.mnPgnStarts), mnCols(rSect.mnCols),
2324 mnColsx(rSect.mnColsx), mnStextflow(rSect.mnStextflow), mnBkc(rSect.mnBkc),
2325 mbLndscpsxn(rSect.mbLndscpsxn), mbTitlepg(rSect.mbTitlepg),
2326 mbFacpgsxn(rSect.mbFacpgsxn), mbRTLsection(rSect.mbRTLsection),
2327 mbPgnrestart(rSect.mbPgnrestart),
2328 mbTitlePageHdFtUsed(rSect.mbTitlePageHdFtUsed),
2329 mbPageHdFtUsed(rSect.mbPageHdFtUsed)
2330 {
2331 };
2332
rtfSection(const SwPosition & rPos,const SectPageInformation & rPageInfo)2333 rtfSection::rtfSection(const SwPosition &rPos,
2334 const SectPageInformation &rPageInfo)
2335 : maStart(rPos.nNode), maPageInfo(rPageInfo), mpSection(0), mpTitlePage(0),
2336 mpPage(0)
2337 {
2338 }
2339
push_back(const rtfSection & rSect)2340 void rtfSections::push_back(const rtfSection &rSect)
2341 {
2342 if (!maSegments.empty() && (maSegments.back().maStart == rSect.maStart))
2343 maSegments.pop_back();
2344 maSegments.push_back(rSect);
2345 }
2346
2347 // lese alle Dokument-Controls ein
SetPageInformationAsDefault(const DocPageInformation & rInfo)2348 void SwRTFParser::SetPageInformationAsDefault(const DocPageInformation &rInfo)
2349 {
2350 //If we are at the beginning of the document then start the document with
2351 //a segment with these properties. See #i14982# for this requirement
2352 rtfSection aSect(*pPam->GetPoint(), SectPageInformation(rInfo));
2353 if (maSegments.empty() || (maSegments.back().maStart == aSect.maStart))
2354 maSegments.push_back(aSect);
2355
2356 if (!bSwPageDesc && IsNewDoc())
2357 {
2358 SwFmtFrmSize aFrmSize(ATT_FIX_SIZE, rInfo.mnPaperw, rInfo.mnPaperh);
2359
2360 SvxLRSpaceItem aLR( static_cast< sal_uInt16 >(rInfo.mnMargl), static_cast< sal_uInt16 >(rInfo.mnMargr), 0, 0, RES_LR_SPACE );
2361 SvxULSpaceItem aUL( static_cast< sal_uInt16 >(rInfo.mnMargt), static_cast< sal_uInt16 >(rInfo.mnMargb), RES_UL_SPACE );
2362
2363 UseOnPage eUseOn;
2364 if (rInfo.mbFacingp)
2365 eUseOn = UseOnPage(nsUseOnPage::PD_MIRROR | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE);
2366 else
2367 eUseOn = UseOnPage(nsUseOnPage::PD_ALL | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE);
2368
2369 sal_uInt16 nPgStart = static_cast< sal_uInt16 >(rInfo.mnPgnStart);
2370
2371 SvxFrameDirectionItem aFrmDir(rInfo.mbRTLdoc ?
2372 FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR);
2373
2374 // direkt an der Standartseite drehen
2375 SwPageDesc& rPg = pDoc->_GetPageDesc( 0 );
2376 rPg.WriteUseOn( eUseOn );
2377
2378 if (rInfo.mbLandscape)
2379 rPg.SetLandscape(true);
2380
2381 SwFrmFmt &rFmt1 = rPg.GetMaster(), &rFmt2 = rPg.GetLeft();
2382
2383 rFmt1.SetFmtAttr( aFrmSize ); rFmt2.SetFmtAttr( aFrmSize );
2384 rFmt1.SetFmtAttr( aLR ); rFmt2.SetFmtAttr( aLR );
2385 rFmt1.SetFmtAttr( aUL ); rFmt2.SetFmtAttr( aUL );
2386 rFmt1.SetFmtAttr( aFrmDir ); rFmt2.SetFmtAttr( aFrmDir );
2387
2388 // StartNummer der Seiten setzen
2389 if (nPgStart != 1)
2390 {
2391 SwFmtPageDesc aPgDsc( &rPg );
2392 aPgDsc.SetNumOffset( nPgStart );
2393 pDoc->InsertPoolItem( *pPam, aPgDsc, 0 );
2394 }
2395 }
2396 }
2397
SetBorderLine(SvxBoxItem & rBox,sal_uInt16 nLine)2398 void SwRTFParser::SetBorderLine(SvxBoxItem& rBox, sal_uInt16 nLine)
2399 {
2400 int bWeiter = true;
2401 short nLineThickness = 1;
2402 short nPageDistance = 0;
2403 sal_uInt8 nCol = 0;
2404 short nIdx = 0;
2405
2406 int nToken = GetNextToken();
2407 do {
2408 switch( nToken )
2409 {
2410 case RTF_BRDRS:
2411 nIdx = 1;
2412 break;
2413
2414 case RTF_BRDRDB:
2415 nIdx = 3;
2416 break;
2417
2418 case RTF_BRDRTRIPLE:
2419 nIdx = 10;
2420 break;
2421
2422 case RTF_BRDRTNTHSG:
2423 nIdx = 11;
2424 break;
2425
2426 case RTF_BRDRTHTNSG:
2427 nIdx = 12;
2428 break;
2429
2430 case RTF_BRDRTNTHTNSG:
2431 nIdx = 13;
2432 break;
2433
2434 case RTF_BRDRTNTHMG:
2435 nIdx = 14;
2436 break;
2437
2438 case RTF_BRDRTHTNMG:
2439 nIdx = 15;
2440 break;
2441
2442 case RTF_BRDRTNTHTNMG:
2443 nIdx = 16;
2444 break;
2445
2446 case RTF_BRDRTNTHLG:
2447 nIdx = 17;
2448 break;
2449
2450 case RTF_BRDRTHTNLG:
2451 nIdx = 18;
2452 break;
2453
2454 case RTF_BRDRTNTHTNLG:
2455 nIdx = 19;
2456 break;
2457
2458 case RTF_BRDRWAVY:
2459 nIdx = 20;
2460 break;
2461
2462 case RTF_BRDRWAVYDB:
2463 nIdx = 21;
2464 break;
2465
2466 case RTF_BRDREMBOSS:
2467 nIdx = 24;
2468 break;
2469
2470 case RTF_BRDRENGRAVE:
2471 nIdx = 25;
2472 break;
2473
2474 case RTF_BRSP:
2475 nPageDistance = static_cast< short >(nTokenValue);
2476 break;
2477
2478 case RTF_BRDRDOT: // SO does not have dashed or dotted lines
2479 case RTF_BRDRDASH:
2480 case RTF_BRDRDASHSM:
2481 case RTF_BRDRDASHD:
2482 case RTF_BRDRDASHDD:
2483 case RTF_BRDRDASHDOTSTR:
2484 case RTF_BRDRSH: // shading not supported
2485 case RTF_BRDRCF: // colors not supported
2486 break;
2487
2488 case RTF_BRDRW:
2489 nLineThickness = static_cast< short >(nTokenValue);
2490 break;
2491 default:
2492 bWeiter = false;
2493 SkipToken(-1);
2494 break;
2495 }
2496 if (bWeiter)
2497 nToken = GetNextToken();
2498 } while (bWeiter && IsParserWorking());
2499
2500 GetLineIndex(rBox, nLineThickness, nPageDistance, nCol, nIdx, nLine, nLine, 0);
2501 }
2502
2503 // lese alle Dokument-Controls ein
ReadDocControls(int nToken)2504 void SwRTFParser::ReadDocControls( int nToken )
2505 {
2506 int bWeiter = true;
2507
2508 SwFtnInfo aFtnInfo;
2509 SwEndNoteInfo aEndInfo;
2510 bool bSetHyph = false;
2511
2512 sal_Bool bEndInfoChgd = sal_False, bFtnInfoChgd = sal_False;
2513
2514 do {
2515 sal_uInt16 nValue = sal_uInt16( nTokenValue );
2516 switch( nToken )
2517 {
2518 case RTF_RTLDOC:
2519 maPageDefaults.mbRTLdoc = true;
2520 break;
2521 case RTF_LTRDOC:
2522 maPageDefaults.mbRTLdoc = false;
2523 break;
2524 case RTF_LANDSCAPE:
2525 maPageDefaults.mbLandscape = true;
2526 break;
2527 case RTF_PAPERW:
2528 if( 0 < nTokenValue )
2529 maPageDefaults.mnPaperw = nTokenValue;
2530 break;
2531 case RTF_PAPERH:
2532 if( 0 < nTokenValue )
2533 maPageDefaults.mnPaperh = nTokenValue;
2534 break;
2535 case RTF_MARGL:
2536 if( 0 <= nTokenValue )
2537 maPageDefaults.mnMargl = nTokenValue;
2538 break;
2539 case RTF_MARGR:
2540 if( 0 <= nTokenValue )
2541 maPageDefaults.mnMargr = nTokenValue;
2542 break;
2543 case RTF_MARGT:
2544 if( 0 <= nTokenValue )
2545 maPageDefaults.mnMargt = nTokenValue;
2546 break;
2547 case RTF_MARGB:
2548 if( 0 <= nTokenValue )
2549 maPageDefaults.mnMargb = nTokenValue;
2550 break;
2551 case RTF_FACINGP:
2552 maPageDefaults.mbFacingp = true;
2553 break;
2554 case RTF_PGNSTART:
2555 maPageDefaults.mnPgnStart = nTokenValue;
2556 break;
2557 case RTF_ENDDOC:
2558 case RTF_ENDNOTES:
2559 aFtnInfo.ePos = FTNPOS_CHAPTER; bFtnInfoChgd = sal_True;
2560 break;
2561 case RTF_FTNTJ:
2562 case RTF_FTNBJ:
2563 aFtnInfo.ePos = FTNPOS_PAGE; bFtnInfoChgd = sal_True;
2564 break;
2565
2566 case RTF_AENDDOC:
2567 case RTF_AENDNOTES:
2568 case RTF_AFTNTJ:
2569 case RTF_AFTNBJ:
2570 case RTF_AFTNRESTART:
2571 case RTF_AFTNRSTCONT:
2572 break; // wir kenn nur am Doc Ende und Doc weite Num.!
2573
2574 case RTF_FTNSTART:
2575 if( nValue )
2576 {
2577 aFtnInfo.nFtnOffset = nValue-1;
2578 bFtnInfoChgd = sal_True;
2579 }
2580 break;
2581 case RTF_AFTNSTART:
2582 if( nValue )
2583 {
2584 aEndInfo.nFtnOffset = nValue-1;
2585 bEndInfoChgd = sal_True;
2586 }
2587 break;
2588 case RTF_FTNRSTPG:
2589 aFtnInfo.eNum = FTNNUM_PAGE; bFtnInfoChgd = sal_True;
2590 break;
2591 case RTF_FTNRESTART:
2592 aFtnInfo.eNum = FTNNUM_CHAPTER; bFtnInfoChgd = sal_True;
2593 break;
2594 case RTF_FTNRSTCONT:
2595 aFtnInfo.eNum = FTNNUM_DOC; bFtnInfoChgd = sal_True;
2596 break;
2597
2598 case RTF_FTNNAR:
2599 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ARABIC); bFtnInfoChgd = sal_True; break;
2600 case RTF_FTNNALC:
2601 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER_N); bFtnInfoChgd = sal_True; break;
2602 case RTF_FTNNAUC:
2603 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_UPPER_LETTER_N); bFtnInfoChgd = sal_True; break;
2604 case RTF_FTNNRLC:
2605 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER); bFtnInfoChgd = sal_True; break;
2606 case RTF_FTNNRUC:
2607 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_UPPER); bFtnInfoChgd = sal_True; break;
2608 case RTF_FTNNCHI:
2609 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL); bFtnInfoChgd = sal_True; break;
2610
2611 case RTF_AFTNNAR:
2612 aEndInfo.aFmt.SetNumberingType(SVX_NUM_ARABIC); bEndInfoChgd = sal_True; break;
2613 case RTF_AFTNNALC:
2614 aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER_N);
2615 bEndInfoChgd = sal_True;
2616 break;
2617 case RTF_AFTNNAUC:
2618 aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_UPPER_LETTER_N);
2619 bEndInfoChgd = sal_True;
2620 break;
2621 case RTF_AFTNNRLC:
2622 aEndInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER);
2623 bEndInfoChgd = sal_True;
2624 break;
2625 case RTF_AFTNNRUC:
2626 aEndInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_UPPER);
2627 bEndInfoChgd = sal_True;
2628 break;
2629 case RTF_AFTNNCHI:
2630 aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
2631 bEndInfoChgd = sal_True;
2632 break;
2633 case RTF_HYPHAUTO:
2634 if (nTokenValue)
2635 bSetHyph = true;
2636 //FOO//
2637 break;
2638 case RTF_PGBRDRT:
2639 SetBorderLine(maPageDefaults.maBox, BOX_LINE_TOP);
2640 break;
2641
2642 case RTF_PGBRDRB:
2643 SetBorderLine(maPageDefaults.maBox, BOX_LINE_BOTTOM);
2644 break;
2645
2646 case RTF_PGBRDRL:
2647 SetBorderLine(maPageDefaults.maBox, BOX_LINE_LEFT);
2648 break;
2649
2650 case RTF_PGBRDRR:
2651 SetBorderLine(maPageDefaults.maBox, BOX_LINE_RIGHT);
2652 break;
2653
2654 case '{':
2655 {
2656 short nSkip = 0;
2657 if( RTF_IGNOREFLAG != GetNextToken() )
2658 nSkip = -1;
2659 else if( RTF_DOCFMT != (( nToken = GetNextToken() )
2660 & ~(0xff | RTF_SWGDEFS)) )
2661 nSkip = -2;
2662 else
2663 {
2664 SkipGroup(); // erstmal komplett ueberlesen
2665 // ueberlese noch die schliessende Klammer
2666 GetNextToken();
2667 }
2668 if( nSkip )
2669 {
2670 SkipToken( nSkip ); // Ignore wieder zurueck
2671 bWeiter = sal_False;
2672 }
2673 }
2674 break;
2675
2676 default:
2677 if( RTF_DOCFMT == (nToken & ~(0xff | RTF_SWGDEFS)) ||
2678 RTF_UNKNOWNCONTROL == nToken )
2679 SvxRTFParser::NextToken( nToken );
2680 else
2681 bWeiter = sal_False;
2682 break;
2683 }
2684 if( bWeiter )
2685 nToken = GetNextToken();
2686 } while( bWeiter && IsParserWorking() );
2687
2688 if (IsNewDoc())
2689 {
2690 if( bEndInfoChgd )
2691 pDoc->SetEndNoteInfo( aEndInfo );
2692 if( bFtnInfoChgd )
2693 pDoc->SetFtnInfo( aFtnInfo );
2694 }
2695
2696 if (!bSwPageDesc)
2697 {
2698 SetPageInformationAsDefault(maPageDefaults);
2699
2700 MakeStyleTab();
2701
2702 SwTxtFmtColl* pColl = aTxtCollTbl.Get(0);
2703 if (!pColl)
2704 {
2705 pColl = pDoc->GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false );
2706 }
2707
2708 ASSERT(pColl, "impossible to have no standard style");
2709
2710 if (pColl)
2711 {
2712 if (
2713 IsNewDoc() && bSetHyph &&
2714 SFX_ITEM_SET != pColl->GetItemState(RES_PARATR_HYPHENZONE,
2715 false)
2716 )
2717 {
2718 pColl->SetFmtAttr(SvxHyphenZoneItem(true, RES_PARATR_HYPHENZONE));
2719 }
2720
2721 pDoc->SetTxtFmtColl( *pPam, pColl );
2722 }
2723 }
2724
2725 SkipToken( -1 );
2726 }
2727
MakeStyleTab()2728 void SwRTFParser::MakeStyleTab()
2729 {
2730 // dann erzeuge aus der SvxStyle-Tabelle die Swg-Collections
2731 if( GetStyleTbl().Count() )
2732 {
2733 sal_uInt16 nValidOutlineLevels = 0;
2734 if( !IsNewDoc() )
2735 {
2736 // search all outlined collections
2737 //sal_uInt8 nLvl;
2738 const SwTxtFmtColls& rColls = *pDoc->GetTxtFmtColls();
2739 for( sal_uInt16 n = rColls.Count(); n; )
2740 //if( MAXLEVEL > (nLvl = rColls[ --n ]->GetOutlineLevel() ))//#outline level,zhaojianwei
2741 // nValidOutlineLevels |= 1 << nLvl;
2742 if( rColls[ --n ]->IsAssignedToListLevelOfOutlineStyle())
2743 nValidOutlineLevels |= 1 << rColls[ n ]->GetAssignedOutlineStyleLevel();//<-end,zhaojianwei
2744 }
2745
2746 SvxRTFStyleType* pStyle = GetStyleTbl().First();
2747 do {
2748 sal_uInt16 nNo = sal_uInt16( GetStyleTbl().GetCurKey() );
2749 if( pStyle->bIsCharFmt )
2750 {
2751 if( !aCharFmtTbl.Get( nNo ) )
2752 // existiert noch nicht, also anlegen
2753 MakeCharStyle( nNo, *pStyle );
2754 }
2755 else if( !aTxtCollTbl.Get( nNo ) )
2756 {
2757 // existiert noch nicht, also anlegen
2758 MakeStyle( nNo, *pStyle );
2759 }
2760
2761 } while( 0 != (pStyle = GetStyleTbl().Next()) );
2762 bStyleTabValid = sal_True;
2763 }
2764 }
2765
lcl_SetFmtCol(SwFmt & rFmt,sal_uInt16 nCols,sal_uInt16 nColSpace,const SvUShorts & rColumns)2766 sal_Bool lcl_SetFmtCol( SwFmt& rFmt, sal_uInt16 nCols, sal_uInt16 nColSpace,
2767 const SvUShorts& rColumns )
2768 {
2769 sal_Bool bSet = sal_False;
2770 if( nCols && USHRT_MAX != nCols )
2771 {
2772 SwFmtCol aCol;
2773 if( USHRT_MAX == nColSpace )
2774 nColSpace = 720;
2775
2776 aCol.Init( nCols, nColSpace, USHRT_MAX );
2777 if( nCols == ( rColumns.Count() / 2 ) )
2778 {
2779 aCol._SetOrtho( sal_False );
2780 sal_uInt16 nWishWidth = 0, nHalfPrev = 0;
2781 for (sal_uInt16 n = 0, i = 0; (n+1) < rColumns.Count(); n += 2, ++i)
2782 {
2783 SwColumn* pCol = aCol.GetColumns()[ i ];
2784 pCol->SetLeft( nHalfPrev );
2785 sal_uInt16 nSp = rColumns[ n+1 ];
2786 nHalfPrev = nSp / 2;
2787 pCol->SetRight( nSp - nHalfPrev );
2788 pCol->SetWishWidth( rColumns[ n ] +
2789 pCol->GetLeft() + pCol->GetRight() );
2790 nWishWidth = nWishWidth + pCol->GetWishWidth();
2791 }
2792 aCol.SetWishWidth( nWishWidth );
2793 }
2794 rFmt.SetFmtAttr( aCol );
2795 bSet = sal_True;
2796 }
2797 return bSet;
2798 }
2799
DoHairyWriterPageDesc(int nToken)2800 void SwRTFParser::DoHairyWriterPageDesc(int nToken)
2801 {
2802 int bWeiter = sal_True;
2803 do {
2804 if( '{' == nToken )
2805 {
2806 switch( nToken = GetNextToken() )
2807 {
2808 case RTF_IGNOREFLAG:
2809 if( RTF_SECTFMT != (( nToken = GetNextToken() )
2810 & ~(0xff | RTF_SWGDEFS)) )
2811 {
2812 SkipToken( -2 ); // Ignore und Token wieder zurueck
2813 bWeiter = sal_False;
2814 break;
2815 }
2816 // kein break, Gruppe ueberspringen
2817
2818 case RTF_FOOTER:
2819 case RTF_HEADER:
2820 case RTF_FOOTERR:
2821 case RTF_HEADERR:
2822 case RTF_FOOTERL:
2823 case RTF_HEADERL:
2824 case RTF_FOOTERF:
2825 case RTF_HEADERF:
2826 SkipGroup(); // erstmal komplett ueberlesen
2827 // ueberlese noch die schliessende Klammer
2828 GetNextToken();
2829 break;
2830
2831 default:
2832 SkipToken( -1 ); // Ignore wieder zurueck
2833 bWeiter = sal_False;
2834 break;
2835 }
2836 }
2837 else if( RTF_SECTFMT == (nToken & ~(0xff | RTF_SWGDEFS)) ||
2838 RTF_UNKNOWNCONTROL == nToken )
2839 SvxRTFParser::NextToken( nToken );
2840 else
2841 bWeiter = sal_False;
2842 if( bWeiter )
2843 nToken = GetNextToken();
2844 } while( bWeiter && IsParserWorking() );
2845 SkipToken( -1 ); // letztes Token wieder zurueck
2846 return;
2847 }
2848
ReadSectControls(int nToken)2849 void SwRTFParser::ReadSectControls( int nToken )
2850 {
2851 //this is some hairy stuff to try and retain writer style page descriptors
2852 //in rtf, almost certainy a bad idea, but we've inherited it, so here it
2853 //stays
2854 if (bInPgDscTbl)
2855 {
2856 DoHairyWriterPageDesc(nToken);
2857 return;
2858 }
2859
2860 ASSERT(!maSegments.empty(), "suspicious to have a section with no "
2861 "page info, though probably legal");
2862 if (maSegments.empty())
2863 {
2864 maSegments.push_back(rtfSection(*pPam->GetPoint(),
2865 SectPageInformation(maPageDefaults)));
2866 }
2867
2868 SectPageInformation aNewSection(maSegments.back().maPageInfo);
2869
2870 bool bNewSection = false;
2871 bool bNewSectionHeader = false;
2872 const SwFmtHeader* _pKeepHeader = NULL;
2873 const SwFmtFooter* _pKeepFooter = NULL;
2874 int bWeiter = true;
2875 bool bKeepFooter = false;
2876 do {
2877 sal_uInt16 nValue = sal_uInt16( nTokenValue );
2878 switch( nToken )
2879 {
2880 case RTF_SECT:
2881 bNewSection = true;
2882 bForceNewTable = true; // #117882#
2883 break;
2884 case RTF_SECTD: {
2885 //Reset to page defaults
2886 SwPageDesc* oldPageDesc=aNewSection.mpPageHdFt;
2887 aNewSection = SectPageInformation(maPageDefaults);
2888 aNewSection.mpPageHdFt=oldPageDesc;
2889 _pKeepHeader = NULL;
2890 _pKeepFooter = NULL;
2891 } break;
2892 case RTF_PGWSXN:
2893 if (0 < nTokenValue)
2894 aNewSection.mnPgwsxn = nTokenValue;
2895 break;
2896 case RTF_PGHSXN:
2897 if (0 < nTokenValue)
2898 aNewSection.mnPghsxn = nTokenValue;
2899 break;
2900 case RTF_MARGLSXN:
2901 if (0 <= nTokenValue)
2902 aNewSection.mnMarglsxn = nTokenValue;
2903 break;
2904 case RTF_MARGRSXN:
2905 if (0 <= nTokenValue)
2906 aNewSection.mnMargrsxn = nTokenValue;
2907 break;
2908 case RTF_MARGTSXN:
2909 if (0 <= nTokenValue)
2910 aNewSection.mnMargtsxn = nTokenValue;
2911 break;
2912 case RTF_MARGBSXN:
2913 if (0 <= nTokenValue)
2914 aNewSection.mnMargbsxn = nTokenValue;
2915 break;
2916 case RTF_FACPGSXN:
2917 aNewSection.mbFacpgsxn = true;
2918 break;
2919 case RTF_HEADERY:
2920 aNewSection.mnHeadery = nTokenValue;
2921 break;
2922 case RTF_FOOTERY:
2923 aNewSection.mnFootery = nTokenValue;
2924 break;
2925 case RTF_LNDSCPSXN:
2926 aNewSection.mbLndscpsxn = true;
2927 break;
2928 case RTF_PGNSTARTS:
2929 aNewSection.mnPgnStarts = nTokenValue;
2930 break;
2931 case RTF_PGNDEC:
2932 aNewSection.maNumType.SetNumberingType(SVX_NUM_ARABIC);
2933 break;
2934 case RTF_PGNUCRM:
2935 aNewSection.maNumType.SetNumberingType(SVX_NUM_ROMAN_UPPER);
2936 break;
2937 case RTF_PGNLCRM:
2938 aNewSection.maNumType.SetNumberingType(SVX_NUM_ROMAN_LOWER);
2939 break;
2940 case RTF_PGNUCLTR:
2941 aNewSection.maNumType.SetNumberingType(
2942 SVX_NUM_CHARS_UPPER_LETTER_N);
2943 break;
2944 case RTF_PGNLCLTR:
2945 aNewSection.maNumType.SetNumberingType(
2946 SVX_NUM_CHARS_LOWER_LETTER_N);
2947 break;
2948 case RTF_SBKNONE:
2949 aNewSection.mnBkc = 0;
2950 break;
2951 case RTF_SBKCOL:
2952 aNewSection.mnBkc = 1;
2953 break;
2954 case RTF_PGBRDRT:
2955 SetBorderLine(aNewSection.maBox, BOX_LINE_TOP);
2956 break;
2957
2958 case RTF_PGBRDRB:
2959 SetBorderLine(aNewSection.maBox, BOX_LINE_BOTTOM);
2960 break;
2961
2962 case RTF_PGBRDRL:
2963 SetBorderLine(aNewSection.maBox, BOX_LINE_LEFT);
2964 break;
2965
2966 case RTF_PGBRDRR:
2967 SetBorderLine(aNewSection.maBox, BOX_LINE_RIGHT);
2968 break;
2969
2970 case RTF_PGBRDROPT:
2971 case RTF_ENDNHERE:
2972 case RTF_BINFSXN:
2973 case RTF_BINSXN:
2974 case RTF_SBKPAGE:
2975 case RTF_SBKEVEN:
2976 case RTF_SBKODD:
2977 case RTF_LINEBETCOL:
2978 case RTF_LINEMOD:
2979 case RTF_LINEX:
2980 case RTF_LINESTARTS:
2981 case RTF_LINERESTART:
2982 case RTF_LINEPAGE:
2983 case RTF_LINECONT:
2984 case RTF_GUTTERSXN:
2985 case RTF_PGNCONT:
2986 case RTF_PGNRESTART:
2987 case RTF_PGNX:
2988 case RTF_PGNY:
2989 case RTF_VERTALT:
2990 case RTF_VERTALB:
2991 case RTF_VERTALC:
2992 case RTF_VERTALJ:
2993 break;
2994 case RTF_TITLEPG:
2995 aNewSection.mbTitlepg = true;
2996 break;
2997 case RTF_HEADER:
2998 case RTF_HEADERL:
2999 case RTF_HEADERR:
3000 if (aNewSection.mpPageHdFt!=NULL)
3001 {
3002 _pKeepHeader = NULL;
3003 bKeepFooter = true; // #i82008
3004 _pKeepFooter = &aNewSection.mpPageHdFt->GetMaster().GetFooter();
3005 }
3006 case RTF_FOOTER:
3007 case RTF_FOOTERL:
3008 case RTF_FOOTERR:
3009 if (aNewSection.mpPageHdFt!=NULL && !bKeepFooter )
3010 {
3011 _pKeepFooter = NULL;
3012 _pKeepHeader = &aNewSection.mpPageHdFt->GetMaster().GetHeader();
3013 }
3014 bKeepFooter = false;
3015 if (!bNewSectionHeader) { //see #117914# topic 2). If a header is redefined in a section
3016 bNewSectionHeader=true; // a new header must be created.
3017 aNewSection.mpPageHdFt=NULL;
3018 }
3019 if (!aNewSection.mpPageHdFt)
3020 {
3021 String aName(RTL_CONSTASCII_STRINGPARAM("rtfHdFt"));
3022 aName += String::CreateFromInt32(maSegments.size());
3023 sal_uInt16 nPageNo = pDoc->MakePageDesc(aName);
3024 aNewSection.mpPageHdFt = &pDoc->_GetPageDesc(nPageNo);
3025 aNewSection.mbPageHdFtUsed = true;
3026 maSegments.maDummyPageNos.push_back(nPageNo);
3027 }
3028 ReadHeaderFooter(nToken, aNewSection.mpPageHdFt);
3029 if (_pKeepHeader) aNewSection.mpPageHdFt->GetMaster().SetFmtAttr(*_pKeepHeader);
3030 if (_pKeepFooter) aNewSection.mpPageHdFt->GetMaster().SetFmtAttr(*_pKeepFooter);
3031 break;
3032 case RTF_FOOTERF:
3033 case RTF_HEADERF:
3034 if (!aNewSection.mpTitlePageHdFt)
3035 {
3036 String aTitle(RTL_CONSTASCII_STRINGPARAM("rtfTitleHdFt"));
3037 aTitle += String::CreateFromInt32(maSegments.size());
3038 sal_uInt16 nPageNo = pDoc->MakePageDesc(aTitle);
3039 aNewSection.mpTitlePageHdFt = &pDoc->_GetPageDesc(nPageNo);
3040 aNewSection.mbTitlePageHdFtUsed = true;
3041 maSegments.maDummyPageNos.push_back(nPageNo);
3042 }
3043 ReadHeaderFooter(nToken, aNewSection.mpTitlePageHdFt);
3044 break;
3045 case RTF_COLS:
3046 aNewSection.mnCols = nTokenValue;
3047 break;
3048 case RTF_COLSX:
3049 aNewSection.mnColsx = nTokenValue;
3050 break;
3051 case RTF_COLNO:
3052 {
3053 // next token must be either colw or colsr
3054 unsigned long nAktCol = nValue;
3055 long nWidth = 0, nSpace = 0;
3056 int nColToken = GetNextToken();
3057 if (RTF_COLW == nColToken)
3058 {
3059 // next token could be colsr (but not required)
3060 nWidth = nTokenValue;
3061 if( RTF_COLSR == GetNextToken() )
3062 nSpace = nTokenValue;
3063 else
3064 SkipToken( -1 ); // put back token
3065 }
3066 else if (RTF_COLSR == nColToken)
3067 {
3068 // next token must be colw (what sense should it make to have colsr only?!)
3069 nSpace = nTokenValue;
3070 if( RTF_COLW == GetNextToken() )
3071 nWidth = nTokenValue;
3072 else
3073 // what should we do if an isolated colsr without colw is found? Doesn't make sense!
3074 SkipToken( -1 ); // put back token
3075 }
3076 else
3077 break;
3078
3079 if (--nAktCol == (aNewSection.maColumns.size() / 2))
3080 {
3081 aNewSection.maColumns.push_back(nWidth);
3082 aNewSection.maColumns.push_back(nSpace);
3083 }
3084 }
3085 break;
3086 case RTF_STEXTFLOW:
3087 aNewSection.mnStextflow = nTokenValue;
3088 break;
3089 case RTF_RTLSECT:
3090 aNewSection.mbRTLsection = true;
3091 break;
3092 case RTF_LTRSECT:
3093 aNewSection.mbRTLsection = false;
3094 break;
3095 case '{':
3096 {
3097 short nSkip = 0;
3098 if( RTF_IGNOREFLAG != ( nToken = GetNextToken() ))
3099 nSkip = -1;
3100 else if( RTF_SECTFMT != (( nToken = GetNextToken() )
3101 & ~(0xff | RTF_SWGDEFS)) &&
3102 ( RTF_DOCFMT != ( nToken & ~(0xff | RTF_SWGDEFS))) )
3103 nSkip = -2;
3104 else
3105 {
3106 // erstmal komplett ueberlesen
3107 SkipGroup();
3108 // ueberlese noch die schliessende Klammer
3109 GetNextToken();
3110 }
3111 if (nSkip)
3112 {
3113 bWeiter = ((-1 == nSkip) &&
3114 (
3115 RTF_FOOTER == nToken || RTF_HEADER == nToken ||
3116 RTF_FOOTERR == nToken || RTF_HEADERR == nToken ||
3117 RTF_FOOTERL == nToken || RTF_HEADERL == nToken ||
3118 RTF_FOOTERF == nToken || RTF_HEADERF == nToken
3119 ));
3120 SkipToken (nSkip); // Ignore wieder zurueck
3121 }
3122 }
3123 break;
3124 case RTF_PAPERW:
3125 case RTF_PAPERH:
3126 case RTF_MARGL:
3127 case RTF_MARGR:
3128 case RTF_MARGT:
3129 case RTF_MARGB:
3130 case RTF_FACINGP:
3131 ASSERT(sal_False, "why are these tokens found in this section?");
3132 ReadDocControls( nToken );
3133 break;
3134 default:
3135 if (RTF_DOCFMT == (nToken & ~(0xff | RTF_SWGDEFS)))
3136 ReadDocControls( nToken );
3137 else if (RTF_SECTFMT == (nToken & ~(0xff | RTF_SWGDEFS)) ||
3138 RTF_UNKNOWNCONTROL == nToken)
3139 {
3140 SvxRTFParser::NextToken(nToken);
3141 }
3142 else
3143 bWeiter = false;
3144 break;
3145 }
3146
3147 if (bWeiter)
3148 nToken = GetNextToken();
3149 } while (bWeiter && IsParserWorking());
3150
3151 if (bNewSection || maSegments.empty())
3152 {
3153 AttrGroupEnd(); //#106493#
3154 if(!bContainsPara && !bContainsTablePara) //#117881#: bContainsTablePara is set in rtftbl.cxx
3155 pDoc->AppendTxtNode(*pPam->GetPoint());
3156 bContainsPara = false;
3157 bContainsTablePara = false;
3158 maSegments.push_back(rtfSection(*pPam->GetPoint(), aNewSection));
3159 }
3160 else //modifying/replacing the current section
3161 {
3162 SwPaM aPamStart(maSegments.back().maStart);
3163 maSegments.pop_back();
3164 maSegments.push_back(rtfSection(*aPamStart.GetPoint(), aNewSection));
3165 }
3166
3167 SkipToken(-1);
3168 }
3169
EnterEnvironment()3170 void SwRTFParser::EnterEnvironment()
3171 {
3172 }
3173
3174
LeaveEnvironment()3175 void SwRTFParser::LeaveEnvironment()
3176 {
3177 if(pRedlineDelete)
3178 {
3179 delete pRedlineDelete;
3180 pRedlineDelete = 0;
3181 }
3182
3183 if(pRedlineInsert)
3184 {
3185 delete pRedlineInsert;
3186 pRedlineInsert = 0;
3187 }
3188 }
3189
SkipPageDescTbl()3190 void SwRTFParser::SkipPageDescTbl()
3191 {
3192 // M.M. #117907# I have to use this glorified SkipGroup because the
3193 // SvParser SkipGroup uses nNextCh which is not set correctly <groan>
3194 int nNumOpenBrakets = 1;
3195
3196 while( nNumOpenBrakets && IsParserWorking() )
3197 {
3198 switch( GetNextToken() )
3199 {
3200 case '}':
3201 {
3202 --nNumOpenBrakets;
3203 }
3204 break;
3205
3206 case '{':
3207 {
3208 nNumOpenBrakets++;
3209 }
3210 break;
3211 }
3212 }
3213
3214 SkipToken( -1 );
3215 }
3216
ReadPageDescTbl()3217 void SwRTFParser::ReadPageDescTbl()
3218 {
3219 // dann erzeuge aus der SvxStyle-Tabelle die Swg-Collections, damit
3220 // diese auch in den Headers/Footer benutzt werden koennen!
3221 MakeStyleTab();
3222 // das default-Style schon gleich am ersten Node setzen
3223 SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 );
3224 if( !pColl )
3225 pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
3226 pDoc->SetTxtFmtColl( *pPam, pColl );
3227
3228 int nToken, bSaveChkStyleAttr = IsChkStyleAttr();
3229 int nNumOpenBrakets = 1; // die erste wurde schon vorher erkannt !!
3230
3231 SetChkStyleAttr(sal_False); // Attribute nicht gegen die Styles checken
3232
3233 bInPgDscTbl = true;
3234 sal_uInt16 nPos = 0;
3235 SwPageDesc* pPg = 0;
3236 SwFrmFmt* pPgFmt = 0;
3237
3238 SvxULSpaceItem aUL( RES_UL_SPACE ), aHUL( RES_UL_SPACE ), aFUL( RES_UL_SPACE );
3239 SvxLRSpaceItem aLR( RES_LR_SPACE ), aHLR( RES_LR_SPACE ), aFLR( RES_LR_SPACE );
3240 Size a4 = SvxPaperInfo::GetPaperSize(PAPER_A4);
3241 SwFmtFrmSize aSz( ATT_FIX_SIZE, a4.Width(), a4.Height() ); // DIN A4 defaulten
3242 SwFmtFrmSize aFSz( ATT_MIN_SIZE ), aHSz( ATT_MIN_SIZE );
3243
3244 SvxFrameDirectionItem aFrmDir(FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR);
3245
3246 sal_uInt16 nCols = USHRT_MAX, nColSpace = USHRT_MAX, nAktCol = 0;
3247 SvUShorts aColumns;
3248 ::std::map< const SwPageDesc*, sal_uInt16 > aFollowMap; //store index of following page descriptors
3249
3250 while( nNumOpenBrakets && IsParserWorking() )
3251 {
3252 switch( nToken = GetNextToken() )
3253 {
3254 case '{':
3255 ++nNumOpenBrakets;
3256 break;
3257 case '}':
3258 if (1 == --nNumOpenBrakets)
3259 {
3260 ASSERT(pPgFmt && pPg, "Serious problem here");
3261 if (pPgFmt && pPg)
3262 {
3263 // PageDesc ist fertig, setze am Doc
3264 pPgFmt->SetFmtAttr(aFrmDir);
3265 pPgFmt->SetFmtAttr(aLR);
3266 pPgFmt->SetFmtAttr(aUL);
3267 pPgFmt->SetFmtAttr(aSz);
3268 ::lcl_SetFmtCol(*pPgFmt, nCols, nColSpace, aColumns);
3269 if (pPgFmt->GetHeader().GetHeaderFmt())
3270 {
3271 SwFrmFmt* pHFmt =
3272 (SwFrmFmt*)pPgFmt->GetHeader().GetHeaderFmt();
3273 pHFmt->SetFmtAttr(aHUL);
3274 pHFmt->SetFmtAttr(aHLR);
3275 pHFmt->SetFmtAttr(aHSz);
3276 }
3277 if (pPgFmt->GetFooter().GetFooterFmt())
3278 {
3279 SwFrmFmt* pFFmt =
3280 (SwFrmFmt*)pPgFmt->GetFooter().GetFooterFmt();
3281 pFFmt->SetFmtAttr(aHUL);
3282 pFFmt->SetFmtAttr(aHLR);
3283 pFFmt->SetFmtAttr(aHSz);
3284 }
3285 if( nPos < pDoc->GetPageDescCnt() )
3286 pDoc->ChgPageDesc(nPos++, *pPg);
3287 }
3288 }
3289 break;
3290 case RTF_PGDSC:
3291 if (nPos) // kein && wg MAC
3292 {
3293 if (nPos != pDoc->MakePageDesc(
3294 String::CreateFromInt32(nTokenValue)))
3295 {
3296 ASSERT( sal_False, "PageDesc an falscher Position" );
3297 }
3298 }
3299 pPg = &pDoc->_GetPageDesc(nPos);
3300 pPg->SetLandscape( sal_False );
3301 pPgFmt = &pPg->GetMaster();
3302 #ifndef CFRONT
3303 SETPAGEDESC_DEFAULTS:
3304 #endif
3305 aSz.SetWidth( a4.Width() ); aSz.SetHeight( a4.Height() );
3306 aLR.SetLeft( 0 ); aLR.SetRight( 0 );
3307 aUL.SetLower( 0 ); aUL.SetUpper( 0 );
3308 aHLR.SetLeft( 0 ); aHLR.SetRight( 0 );
3309 aHUL.SetLower( 0 ); aHUL.SetUpper( 0 );
3310 aFLR.SetLeft( 0 ); aFLR.SetRight( 0 );
3311 aFUL.SetLower( 0 ); aFUL.SetUpper( 0 );
3312 nCols = USHRT_MAX; nColSpace = USHRT_MAX; nAktCol = 0;
3313 aFSz.SetHeightSizeType( ATT_MIN_SIZE ); aFSz.SetHeight( 0 );
3314 aHSz.SetHeightSizeType( ATT_MIN_SIZE ); aHSz.SetHeight( 0 );
3315 break;
3316
3317 case RTF_PGDSCUSE:
3318 pPg->WriteUseOn( (UseOnPage)nTokenValue );
3319 break;
3320
3321 case RTF_PGDSCNXT:
3322 // store index of follow in map; will be fixed up later
3323 if( nTokenValue )
3324 aFollowMap.insert( ::std::pair<const SwPageDesc*, sal_uInt16>( pPg, nTokenValue ));
3325 else
3326 pPg->SetFollow( & const_cast<const SwDoc *>(pDoc)
3327 ->GetPageDesc( 0 ) );
3328 break;
3329
3330 case RTF_FORMULA: /* Zeichen "\|" !!! */
3331 pPgFmt->SetFmtAttr( aLR );
3332 pPgFmt->SetFmtAttr( aUL );
3333 pPgFmt->SetFmtAttr( aSz );
3334 ::lcl_SetFmtCol( *pPgFmt, nCols, nColSpace, aColumns );
3335 if( pPgFmt->GetHeader().GetHeaderFmt() )
3336 {
3337 SwFrmFmt* pHFmt = (SwFrmFmt*)pPgFmt->GetHeader().GetHeaderFmt();
3338 pHFmt->SetFmtAttr( aHUL );
3339 pHFmt->SetFmtAttr( aHLR );
3340 pHFmt->SetFmtAttr( aHSz );
3341 }
3342 if( pPgFmt->GetFooter().GetFooterFmt() )
3343 {
3344 SwFrmFmt* pFFmt = (SwFrmFmt*)pPgFmt->GetFooter().GetFooterFmt();
3345 pFFmt->SetFmtAttr( aHUL );
3346 pFFmt->SetFmtAttr( aHLR );
3347 pFFmt->SetFmtAttr( aHSz );
3348 }
3349
3350 pPgFmt = &pPg->GetLeft();
3351 #ifndef CFRONT
3352 goto SETPAGEDESC_DEFAULTS;
3353 #else
3354 aLR.SetLeft( 0 ); aLR.SetRight( 0 );
3355 aUL.SetLower( 0 ); aUL.SetUpper( 0 );
3356 aHLR.SetLeft( 0 ); aHLR.SetRight( 0 );
3357 aHUL.SetLower( 0 ); aHUL.SetUpper( 0 );
3358 aFLR.SetLeft( 0 ); aFLR.SetRight( 0 );
3359 aFUL.SetLower( 0 ); aFUL.SetUpper( 0 );
3360 aSz.SetWidth( a4.Width() ); aSz.SetHeight( a4.Height() ); // DIN A4 default
3361 nCols = USHRT_MAX; nColSpace = USHRT_MAX; nAktCol = 0;
3362 aFSz.SetHeightSizeType( ATT_MIN_SIZE ); aFSz.SetHeight( 0 );
3363 aHSz.SetHeightSizeType( ATT_MIN_SIZE ); aHSz.SetHeight( 0 );
3364 break;
3365 #endif
3366
3367 case RTF_RTLSECT:
3368 aFrmDir.SetValue(FRMDIR_HORI_RIGHT_TOP);
3369 break;
3370
3371 case RTF_LTRSECT:
3372 aFrmDir.SetValue(FRMDIR_HORI_LEFT_TOP);
3373 break;
3374
3375 // alt: LI/RI/SA/SB, neu: MARG?SXN
3376 case RTF_MARGLSXN:
3377 case RTF_LI: aLR.SetLeft( (sal_uInt16)nTokenValue ); break;
3378 case RTF_MARGRSXN:
3379 case RTF_RI: aLR.SetRight( (sal_uInt16)nTokenValue ); break;
3380 case RTF_MARGTSXN:
3381 case RTF_SA: aUL.SetUpper( (sal_uInt16)nTokenValue ); break;
3382 case RTF_MARGBSXN:
3383 case RTF_SB: aUL.SetLower( (sal_uInt16)nTokenValue ); break;
3384 case RTF_PGWSXN: aSz.SetWidth( nTokenValue ); break;
3385 case RTF_PGHSXN: aSz.SetHeight( nTokenValue ); break;
3386
3387 case RTF_HEADERY: aHUL.SetUpper( (sal_uInt16)nTokenValue ); break;
3388 case RTF_HEADER_YB: aHUL.SetLower( (sal_uInt16)nTokenValue ); break;
3389 case RTF_HEADER_XL: aHLR.SetLeft( (sal_uInt16)nTokenValue ); break;
3390 case RTF_HEADER_XR: aHLR.SetRight( (sal_uInt16)nTokenValue ); break;
3391 case RTF_FOOTERY: aFUL.SetLower( (sal_uInt16)nTokenValue ); break;
3392 case RTF_FOOTER_YT: aFUL.SetUpper( (sal_uInt16)nTokenValue ); break;
3393 case RTF_FOOTER_XL: aFLR.SetLeft( (sal_uInt16)nTokenValue ); break;
3394 case RTF_FOOTER_XR: aFLR.SetRight( (sal_uInt16)nTokenValue ); break;
3395
3396 case RTF_HEADER_YH:
3397 if( 0 > nTokenValue )
3398 {
3399 aHSz.SetHeightSizeType( ATT_FIX_SIZE );
3400 nTokenValue = -nTokenValue;
3401 }
3402 aHSz.SetHeight( (sal_uInt16)nTokenValue );
3403 break;
3404
3405 case RTF_FOOTER_YH:
3406 if( 0 > nTokenValue )
3407 {
3408 aFSz.SetHeightSizeType( ATT_FIX_SIZE );
3409 nTokenValue = -nTokenValue;
3410 }
3411 aFSz.SetHeight( (sal_uInt16)nTokenValue );
3412 break;
3413
3414
3415 case RTF_LNDSCPSXN: pPg->SetLandscape( sal_True ); break;
3416
3417 case RTF_COLS: nCols = (sal_uInt16)nTokenValue; break;
3418 case RTF_COLSX: nColSpace = (sal_uInt16)nTokenValue; break;
3419
3420 case RTF_COLNO:
3421 nAktCol = (sal_uInt16)nTokenValue;
3422 if( RTF_COLW == GetNextToken() )
3423 {
3424 sal_uInt16 nWidth = sal_uInt16( nTokenValue ), nSpace = 0;
3425 if( RTF_COLSR == GetNextToken() )
3426 nSpace = sal_uInt16( nTokenValue );
3427 else
3428 SkipToken( -1 ); // wieder zurueck
3429
3430 if( --nAktCol == ( aColumns.Count() / 2 ) )
3431 {
3432 aColumns.Insert( nWidth, aColumns.Count() );
3433 aColumns.Insert( nSpace, aColumns.Count() );
3434 }
3435 }
3436 break;
3437
3438 case RTF_PAGEBB:
3439 {
3440 pPgFmt->SetFmtAttr( SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK ) );
3441 }
3442 break;
3443
3444 case RTF_HEADER:
3445 case RTF_HEADERL:
3446 case RTF_HEADERR:
3447 case RTF_FOOTER:
3448 case RTF_FOOTERL:
3449 case RTF_FOOTERR:
3450 case RTF_FOOTERF:
3451 case RTF_HEADERF:
3452 ReadHeaderFooter(nToken, pPg);
3453 --nNumOpenBrakets; // Klammer wird im ReadAttr ueberlesen!
3454 break;
3455 case RTF_TEXTTOKEN:
3456 if (!DelCharAtEnd(aToken, ';' ).Len())
3457 break;
3458 ASSERT(pPg, "Unexpected missing pPg");
3459 if (pPg)
3460 {
3461 pPg->SetName(aToken);
3462
3463 // sollte es eine Vorlage aus dem Pool sein ??
3464 sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(aToken,
3465 nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC);
3466 if (USHRT_MAX != n)
3467 {
3468 // dann setze bei der Neuen die entsp. PoolId
3469 pPg->SetPoolFmtId(n);
3470 }
3471 }
3472 break;
3473 case RTF_BRDBOX:
3474 if (3 == nNumOpenBrakets)
3475 {
3476 ReadBorderAttr(SkipToken(-2),
3477 (SfxItemSet&)pPgFmt->GetAttrSet());
3478 --nNumOpenBrakets; // Klammer wird im ReadAttr ueberlesen!
3479 }
3480 break;
3481 case RTF_SHADOW:
3482 if( 3 == nNumOpenBrakets )
3483 {
3484 ReadAttr( SkipToken( -2 ), (SfxItemSet*)&pPgFmt->GetAttrSet() );
3485 --nNumOpenBrakets; // Klammer wird im ReadAttr ueberlesen!
3486 }
3487 break;
3488
3489
3490 default:
3491 if( (nToken & ~0xff ) == RTF_SHADINGDEF )
3492 ReadBackgroundAttr( nToken, (SfxItemSet&)pPgFmt->GetAttrSet() );
3493 break;
3494 }
3495 }
3496
3497
3498 // setze jetzt noch bei allen die entsprechenden Follows !!
3499 // Die, die ueber die Tabelle eingelesen wurden und einen
3500 // Follow definiert haben, ist dieser als Tabposition im
3501 // Follow schon gesetzt.
3502 for( nPos = 0; nPos < pDoc->GetPageDescCnt(); ++nPos )
3503 {
3504 SwPageDesc* pPgDsc = &pDoc->_GetPageDesc( nPos );
3505 std::map< const SwPageDesc*, sal_uInt16 >::const_iterator aIter =
3506 aFollowMap.find( pPgDsc );
3507 if (aIter != aFollowMap.end())
3508 {
3509 if ((*aIter).second < pDoc->GetPageDescCnt())
3510 pPgDsc->SetFollow(& const_cast<const SwDoc *>(pDoc)->GetPageDesc((*aIter).second));
3511 }
3512 }
3513
3514 SetChkStyleAttr( bSaveChkStyleAttr );
3515
3516 bInPgDscTbl = false;
3517 nAktPageDesc = 0;
3518 nAktFirstPageDesc = 0;
3519 bSwPageDesc = true;
3520 SkipToken( -1 );
3521 }
3522
3523 // -------------- Methoden --------------------
3524
3525 /*
3526 void SwRTFParser::ReadUnknownData()
3527 {
3528 SvRTFParser::ReadUnknownData();
3529 }
3530
3531 void SwRTFParser::ReadOLEData()
3532 {
3533 SvRTFParser::ReadOLEData();
3534 }
3535 */
3536
ReadPrtData()3537 void SwRTFParser::ReadPrtData()
3538 {
3539 while( IsParserWorking() )
3540 {
3541 int nToken = GetNextToken();
3542 if( (RTF_TEXTTOKEN != nToken) && ('}' == nToken) )
3543 break;
3544 }
3545
3546 SkipToken( -1 ); // schliessende Klammer wieder zurueck!!
3547 }
3548
SetHeader(SwFrmFmt * pHdFtFmt,sal_Bool bReuseOld)3549 static const SwNodeIndex* SetHeader(SwFrmFmt* pHdFtFmt, sal_Bool bReuseOld)
3550 {
3551 ASSERT(pHdFtFmt, "Impossible, no header");
3552 const SwFrmFmt* pExisting = bReuseOld ?
3553 pHdFtFmt->GetHeader().GetHeaderFmt() : 0;
3554 if (!pExisting)
3555 {
3556 //No existing header, create a new one
3557 pHdFtFmt->SetFmtAttr(SwFmtHeader(sal_True));
3558 pExisting = pHdFtFmt->GetHeader().GetHeaderFmt();
3559 }
3560 return pExisting->GetCntnt().GetCntntIdx();
3561 }
3562
SetFooter(SwFrmFmt * pHdFtFmt,sal_Bool bReuseOld)3563 static const SwNodeIndex* SetFooter(SwFrmFmt* pHdFtFmt, sal_Bool bReuseOld)
3564 {
3565 ASSERT(pHdFtFmt, "Impossible, no footer");
3566 const SwFrmFmt* pExisting = bReuseOld ?
3567 pHdFtFmt->GetFooter().GetFooterFmt() : 0;
3568 if (!pExisting)
3569 {
3570 //No exist footer, create a new one
3571 pHdFtFmt->SetFmtAttr(SwFmtFooter(sal_True));
3572 pExisting = pHdFtFmt->GetFooter().GetFooterFmt();
3573 }
3574 return pExisting->GetCntnt().GetCntntIdx();
3575 }
3576
3577
ReadHeaderFooter(int nToken,SwPageDesc * pPageDesc)3578 void SwRTFParser::ReadHeaderFooter( int nToken, SwPageDesc* pPageDesc )
3579 {
3580 ASSERT( RTF_FOOTNOTE == nToken ||
3581 RTF_FLY_INPARA == nToken ||
3582 pPageDesc, "PageDesc is missing" );
3583
3584 bool bContainsParaCache = bContainsPara;
3585 // backup all important data
3586 SwPosition aSavePos( *pPam->GetPoint() );
3587 SvxRTFItemStack aSaveStack(GetAttrStack());
3588 GetAttrStack().clear();
3589
3590 // save the fly array - after read, all flys may be set into
3591 // the header/footer
3592 SwFlySaveArr aSaveArray( 255 < aFlyArr.Count() ? aFlyArr.Count() : 255 );
3593 aSaveArray.Insert( &aFlyArr, 0 );
3594 aFlyArr.Remove( 0, aFlyArr.Count() );
3595 sal_Bool bSetFlyInDoc = sal_True;
3596
3597 const SwNodeIndex* pSttIdx = 0;
3598 SwFrmFmt* pHdFtFmt = 0;
3599 SwTxtAttr* pTxtAttr = 0;
3600 int bDelFirstChar = sal_False;
3601 bool bOldIsFootnote = mbIsFootnote;
3602 sal_Bool bOldGrpStt = sal::static_int_cast< sal_Bool, int >(IsNewGroup());
3603
3604 int nNumOpenBrakets = GetOpenBrakets() - 1;
3605
3606 switch( nToken )
3607 {
3608 case RTF_FOOTNOTE:
3609 {
3610 bool bIsEndNote = RTF_FTNALT == GetNextToken();
3611 if (!bIsEndNote)
3612 SkipToken(-1);
3613
3614 SwTxtNode* pTxtNd = pPam->GetNode()->GetTxtNode();
3615 SwFmtFtn aFtnNote(bIsEndNote);
3616 xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex();
3617
3618 if (nPos && !bFootnoteAutoNum)
3619 {
3620 pPam->GetPoint()->nContent--;
3621 nPos--;
3622 aFtnNote.SetNumStr( pTxtNd->GetTxt().GetChar( nPos ) );
3623 ((String&)pTxtNd->GetTxt()).SetChar( nPos, CH_TXTATR_INWORD );
3624 bDelFirstChar = sal_True;
3625 }
3626
3627 pTxtAttr = pTxtNd->InsertItem( aFtnNote, nPos, nPos,
3628 bDelFirstChar ? nsSetAttrMode::SETATTR_NOTXTATRCHR : 0 );
3629
3630 ASSERT( pTxtAttr, "konnte die Fussnote nicht einfuegen/finden" );
3631
3632 if( pTxtAttr )
3633 pSttIdx = ((SwTxtFtn*)pTxtAttr)->GetStartNode();
3634 mbIsFootnote = true;
3635
3636 // wurde an der Position ein Escapement aufgespannt, so entferne
3637 // das jetzt. Fussnoten sind bei uns immer hochgestellt.
3638 SvxRTFItemStackTypePtr pTmp = aSaveStack.empty() ? 0 : aSaveStack.back();
3639 if( pTmp && pTmp->GetSttNodeIdx() ==
3640 pPam->GetPoint()->nNode.GetIndex() &&
3641 pTmp->GetSttCnt() == nPos )
3642 pTmp->GetAttrSet().ClearItem( RES_CHRATR_ESCAPEMENT );
3643 }
3644 break;
3645
3646 case RTF_FLY_INPARA:
3647 {
3648 xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex();
3649 SfxItemSet aSet( pDoc->GetAttrPool(), RES_FRMATR_BEGIN,
3650 RES_FRMATR_END-1 );
3651 aSet.Put( SwFmtAnchor( FLY_AS_CHAR ));
3652 pHdFtFmt = pDoc->MakeFlySection( FLY_AS_CHAR,
3653 pPam->GetPoint(), &aSet );
3654
3655 pTxtAttr = pPam->GetNode()->GetTxtNode()->GetTxtAttrForCharAt(
3656 nPos, RES_TXTATR_FLYCNT );
3657 ASSERT( pTxtAttr, "konnte den Fly nicht einfuegen/finden" );
3658
3659 pSttIdx = pHdFtFmt->GetCntnt().GetCntntIdx();
3660 bSetFlyInDoc = sal_False;
3661 }
3662 break;
3663
3664 case RTF_HEADERF:
3665 case RTF_HEADER:
3666 pPageDesc->WriteUseOn( (UseOnPage)(pPageDesc->ReadUseOn() | nsUseOnPage::PD_HEADERSHARE) );
3667 pHdFtFmt = &pPageDesc->GetMaster();
3668 pSttIdx = SetHeader( pHdFtFmt, sal_False );
3669 break;
3670
3671 case RTF_HEADERL:
3672 // we cannot have left or right, must have always both
3673 pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_HEADERSHARE) | nsUseOnPage::PD_ALL));
3674 SetHeader( pPageDesc->GetRightFmt(), sal_True );
3675 pHdFtFmt = pPageDesc->GetLeftFmt();
3676 pSttIdx = SetHeader(pHdFtFmt, sal_False );
3677 break;
3678
3679 case RTF_HEADERR:
3680 // we cannot have left or right, must have always both
3681 pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_HEADERSHARE) | nsUseOnPage::PD_ALL));
3682 SetHeader( pPageDesc->GetLeftFmt(), sal_True );
3683 pHdFtFmt = pPageDesc->GetRightFmt();
3684 pSttIdx = SetHeader(pHdFtFmt, sal_False );
3685 break;
3686
3687 case RTF_FOOTERF:
3688 case RTF_FOOTER:
3689 pPageDesc->WriteUseOn( (UseOnPage)(pPageDesc->ReadUseOn() | nsUseOnPage::PD_FOOTERSHARE) );
3690 pHdFtFmt = &pPageDesc->GetMaster();
3691 pSttIdx = SetFooter(pHdFtFmt, sal_False );
3692 break;
3693
3694 case RTF_FOOTERL:
3695 // we cannot have left or right, must have always both
3696 pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_FOOTERSHARE) | nsUseOnPage::PD_ALL));
3697 SetFooter( pPageDesc->GetRightFmt(), sal_True );
3698 pHdFtFmt = pPageDesc->GetLeftFmt();
3699 pSttIdx = SetFooter(pHdFtFmt, sal_False );
3700 break;
3701
3702 case RTF_FOOTERR:
3703 // we cannot have left or right, must have always both
3704 pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_FOOTERSHARE) | nsUseOnPage::PD_ALL));
3705 SetFooter( pPageDesc->GetLeftFmt(), sal_True );
3706 pHdFtFmt = pPageDesc->GetRightFmt();
3707 pSttIdx = SetFooter(pHdFtFmt, sal_False );
3708 break;
3709 }
3710
3711 sal_uInt16 nOldFlyArrCnt = aFlyArr.Count();
3712 if( !pSttIdx )
3713 SkipGroup();
3714 else
3715 {
3716 // es ist auf jedenfall jetzt ein TextNode im Kopf/Fusszeilen-Bereich
3717 // vorhanden. Dieser muss jetzt nur noch gefunden und der neue Cursor
3718 // dort hinein gesetzt werden.
3719 SwCntntNode *pNode = pDoc->GetNodes()[ pSttIdx->GetIndex()+1 ]->
3720 GetCntntNode();
3721
3722 // immer ans Ende der Section einfuegen !!
3723 pPam->GetPoint()->nNode = *pNode->EndOfSectionNode();
3724 pPam->Move( fnMoveBackward );
3725
3726 SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 );
3727 if( !pColl )
3728 pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
3729 pDoc->SetTxtFmtColl( *pPam, pColl );
3730
3731 SetNewGroup( sal_True );
3732
3733 while( !( nNumOpenBrakets == GetOpenBrakets() && !GetStackPos()) && IsParserWorking() )
3734 {
3735 switch( nToken = GetNextToken() )
3736 {
3737 case RTF_U:
3738 if( bDelFirstChar )
3739 {
3740 bDelFirstChar = sal_False;
3741 nToken = 0;
3742 }
3743 break;
3744
3745 case RTF_TEXTTOKEN:
3746 if( bDelFirstChar )
3747 {
3748 if( !aToken.Erase( 0, 1 ).Len() )
3749 nToken = 0;
3750 bDelFirstChar = sal_False;
3751 }
3752 break;
3753 }
3754 if( nToken )
3755 NextToken( nToken );
3756 }
3757
3758 SetAllAttrOfStk();
3759 if( aFlyArr.Count() && bSetFlyInDoc )
3760 SetFlysInDoc();
3761
3762 // sollte der letze Node leer sein, dann loesche ihn
3763 // (\par heisst ja Absatzende und nicht neuer Absatz!)
3764 DelLastNode();
3765 }
3766
3767 // vom FlyFmt noch die richtigen Attribute setzen
3768 if( pTxtAttr && RES_TXTATR_FLYCNT == pTxtAttr->Which() )
3769 {
3770 // is add a new fly ?
3771 if( nOldFlyArrCnt < aFlyArr.Count() )
3772 {
3773 SwFlySave* pFlySave = aFlyArr[ aFlyArr.Count()-1 ];
3774 pFlySave->aFlySet.ClearItem( RES_ANCHOR );
3775 pHdFtFmt->SetFmtAttr( pFlySave->aFlySet );
3776 aFlyArr.DeleteAndDestroy( aFlyArr.Count() - 1 );
3777 }
3778 else
3779 {
3780 // no, so remove the created textattribute
3781 SwFrmFmt* pFlyFmt = pTxtAttr->GetFlyCnt().GetFrmFmt();
3782 // remove the pam from the flynode
3783 *pPam->GetPoint() = aSavePos;
3784 pDoc->DelLayoutFmt( pFlyFmt );
3785 }
3786 }
3787
3788 bFootnoteAutoNum = sal_False; // default auf aus!
3789
3790 // und alles wieder zurueck
3791 *pPam->GetPoint() = aSavePos;
3792 if (mbIsFootnote)
3793 SetNewGroup( bOldGrpStt ); // Status wieder zurueck
3794 else
3795 SetNewGroup( sal_False ); // { - Klammer war kein Group-Start!
3796 mbIsFootnote = bOldIsFootnote;
3797 GetAttrStack() = aSaveStack;
3798
3799 aFlyArr.Insert( &aSaveArray, 0 );
3800 aSaveArray.Remove( 0, aSaveArray.Count() );
3801 bContainsPara = bContainsParaCache;
3802 }
3803
SetSwgValues(SfxItemSet & rSet)3804 void SwRTFParser::SetSwgValues( SfxItemSet& rSet )
3805 {
3806 const SfxPoolItem* pItem;
3807 // Escapement korrigieren
3808 if( SFX_ITEM_SET == rSet.GetItemState( RES_CHRATR_ESCAPEMENT, sal_False, &pItem ))
3809 {
3810 /* prozentuale Veraenderung errechnen !
3811 * Formel : (FontSize * 1/20 ) pts Escapement * 2
3812 * ----------------------- = ----------------
3813 * 100% x
3814 */
3815
3816 // die richtige
3817 long nEsc = ((SvxEscapementItem*)pItem)->GetEsc();
3818
3819 // automatische Ausrichtung wurde schon richtig berechnet
3820 if( DFLT_ESC_AUTO_SUPER != nEsc && DFLT_ESC_AUTO_SUB != nEsc )
3821 {
3822 const SvxFontHeightItem& rFH = GetSize( rSet );
3823 nEsc *= 1000L;
3824 if(rFH.GetHeight()) nEsc /= long(rFH.GetHeight()); // #i77256#
3825
3826 SvxEscapementItem aEsc( (short) nEsc,
3827 ((SvxEscapementItem*)pItem)->GetProp(), RES_CHRATR_ESCAPEMENT);
3828 rSet.Put( aEsc );
3829 }
3830 }
3831
3832 // TabStops anpassen
3833 if( SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_TABSTOP, sal_False, &pItem ))
3834 {
3835 const SvxLRSpaceItem& rLR = GetLRSpace( rSet );
3836 SvxTabStopItem aTStop( *(SvxTabStopItem*)pItem );
3837
3838 long nOffset = rLR.GetTxtLeft();
3839 if( nOffset )
3840 {
3841 // Tabs anpassen !!
3842 SvxTabStop* pTabs = (SvxTabStop*)aTStop.GetStart();
3843 for( sal_uInt16 n = aTStop.Count(); n; --n, ++pTabs)
3844 if( SVX_TAB_ADJUST_DEFAULT != pTabs->GetAdjustment() )
3845 pTabs->GetTabPos() -= nOffset;
3846
3847 // negativer Einzug, dann auf 0 Pos einen Tab setzen
3848 if( rLR.GetTxtFirstLineOfst() < 0 )
3849 aTStop.Insert( SvxTabStop() );
3850 }
3851
3852 if( !aTStop.Count() )
3853 {
3854 const SvxTabStopItem& rDflt = (const SvxTabStopItem&)rSet.
3855 GetPool()->GetDefaultItem(RES_PARATR_TABSTOP);
3856 if( rDflt.Count() )
3857 aTStop.Insert( &rDflt, 0 );
3858 }
3859 rSet.Put( aTStop );
3860 }
3861 else if( SFX_ITEM_SET == rSet.GetItemState( RES_LR_SPACE, sal_False, &pItem )
3862 && ((SvxLRSpaceItem*)pItem)->GetTxtFirstLineOfst() < 0 )
3863 {
3864 // negativer Einzug, dann auf 0 Pos einen Tab setzen
3865 rSet.Put( SvxTabStopItem( 1, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP ));
3866 }
3867
3868 // NumRules anpassen
3869 if( !bStyleTabValid &&
3870 SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_NUMRULE, sal_False, &pItem ))
3871 {
3872 // dann steht im Namen nur ein Verweis in das ListArray
3873 SwNumRule* pRule = GetNumRuleOfListNo( ((SwNumRuleItem*)pItem)->
3874 GetValue().ToInt32() );
3875 if( pRule )
3876 rSet.Put( SwNumRuleItem( pRule->GetName() ));
3877 else
3878 rSet.ClearItem( RES_PARATR_NUMRULE );
3879
3880 }
3881
3882
3883 /*
3884 ????????????????????????????????????????????????????????????????????
3885 ?? muss die LineSpacing Hoehe 200Twip betragen ??
3886 ?? in rtfitem.hxx wird es auf 0 defaultet. Wenn ja, dann muss hier
3887 ?? ein neues Item gesetzt werden!!!!
3888 ????????????????????????????????????????????????????????????????????
3889
3890 // LineSpacing korrigieren
3891 if( SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_LINESPACING, sal_False, &pItem ))
3892 {
3893 const SvxLineSpacingItem* pLS = (const SvxLineSpacingItem*)pItem;
3894 SvxLineSpacingItem aNew;
3895
3896 aNew.SetInterLineSpace( pLS->GetInterLineSpace() );
3897 aNew.GetLineSpaceRule() = pLS->GetLineSpaceRule();
3898 aNew.SetPropLineSpace( pLS->GetPropLineSpace() );
3899 aNew.GetInterLineSpaceRule() = pLS->GetInterLineSpaceRule();
3900
3901 rSet.Put( aNew );
3902 }
3903 ?????????????????????????????????????????????????????????????????? */
3904
3905 }
3906
3907
MakeColl(const String & rName,sal_uInt16 nPos,sal_uInt8 nOutlineLevel,bool & rbCollExist)3908 SwTxtFmtColl* SwRTFParser::MakeColl(const String& rName, sal_uInt16 nPos,
3909 sal_uInt8 nOutlineLevel, bool& rbCollExist)
3910 {
3911 if( sal_uInt8(-1) == nOutlineLevel )
3912 //nOutlineLevel = NO_NUMBERING;
3913 nOutlineLevel = MAXLEVEL;//#outline level,zhaojianwei
3914
3915 rbCollExist = false;
3916 SwTxtFmtColl* pColl;
3917 String aNm( rName );
3918 if( !aNm.Len() )
3919 {
3920 ASSERT(sal_False, "not a bug, but I (cmc) want to see an example of this");
3921 if( !nPos )
3922 {
3923 pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
3924 if ( nOutlineLevel < MAXLEVEL )
3925 pColl->AssignToListLevelOfOutlineStyle( nOutlineLevel );
3926 else
3927 pColl->DeleteAssignmentToListLevelOfOutlineStyle();
3928 return pColl;
3929 }
3930
3931 // erzeuge einen Namen
3932 aNm.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NoName(" ));
3933 aNm += String::CreateFromInt32( nPos );
3934 aNm += ')';
3935 }
3936 ww::sti eSti = ww::GetCanonicalStiFromEnglishName(rName);
3937 sw::util::ParaStyleMapper::StyleResult aResult =
3938 maParaStyleMapper.GetStyle(rName, eSti);
3939 pColl = aResult.first;
3940 rbCollExist = aResult.second;
3941 if (IsNewDoc() && rbCollExist)
3942 {
3943 // --> OD 2007-01-25 #i73790# - method renamed
3944 pColl->ResetAllFmtAttr();
3945 // <--
3946 rbCollExist = false;
3947 }
3948
3949 if (!rbCollExist)
3950 {
3951 //pColl->SetOutlineLevel( nOutlineLevel ); //#outline level,removed by zhaojianwei
3952 if(nOutlineLevel < MAXLEVEL) //->add by zhaojianwei
3953 pColl->AssignToListLevelOfOutlineStyle( nOutlineLevel );
3954 else
3955 pColl->DeleteAssignmentToListLevelOfOutlineStyle(); //<-end,zhaojianwei
3956 }
3957
3958 return pColl;
3959 }
3960
MakeCharFmt(const String & rName,sal_uInt16 nPos,int & rbCollExist)3961 SwCharFmt* SwRTFParser::MakeCharFmt(const String& rName, sal_uInt16 nPos,
3962 int& rbCollExist)
3963 {
3964 rbCollExist = sal_False;
3965 SwCharFmt* pFmt;
3966 String aNm( rName );
3967 if( !aNm.Len() )
3968 {
3969 ASSERT(sal_False, "not a bug, but I (cmc) want to see an example of this");
3970 aNm.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NoName(" ));
3971 aNm += String::CreateFromInt32( nPos );
3972 aNm += ')';
3973 }
3974
3975 ww::sti eSti = ww::GetCanonicalStiFromEnglishName(rName);
3976 sw::util::CharStyleMapper::StyleResult aResult =
3977 maCharStyleMapper.GetStyle(rName, eSti);
3978 pFmt = aResult.first;
3979 rbCollExist = aResult.second;
3980 if (IsNewDoc() && rbCollExist)
3981 {
3982 // --> OD 2007-01-25 #i73790# - method renamed
3983 pFmt->ResetAllFmtAttr();
3984 // <--
3985 rbCollExist = false;
3986 }
3987 return pFmt;
3988 }
3989
SetStyleAttr(SfxItemSet & rCollSet,const SfxItemSet & rStyleSet,const SfxItemSet & rDerivedSet)3990 void SwRTFParser::SetStyleAttr( SfxItemSet& rCollSet,
3991 const SfxItemSet& rStyleSet,
3992 const SfxItemSet& rDerivedSet )
3993 {
3994 rCollSet.Put( rStyleSet );
3995 if( rDerivedSet.Count() )
3996 {
3997 // suche alle Attribute, die neu gesetzt werden:
3998 const SfxPoolItem* pItem;
3999 SfxItemIter aIter( rDerivedSet );
4000 sal_uInt16 nWhich = aIter.GetCurItem()->Which();
4001 while( sal_True )
4002 {
4003 switch( rStyleSet.GetItemState( nWhich, sal_False, &pItem ) )
4004 {
4005 case SFX_ITEM_DEFAULT:
4006 // auf default zuruecksetzen
4007 if( RES_FRMATR_END > nWhich )
4008 rCollSet.Put( rCollSet.GetPool()->GetDefaultItem( nWhich ));
4009 break;
4010 case SFX_ITEM_SET:
4011 if( *pItem == *aIter.GetCurItem() ) // gleiches Attribut?
4012 // definition kommt aus dem Parent
4013 rCollSet.ClearItem( nWhich ); // loeschen
4014 break;
4015 }
4016
4017 if( aIter.IsAtEnd() )
4018 break;
4019 nWhich = aIter.NextItem()->Which();
4020 }
4021 }
4022 // und jetzt noch auf unsere Werte abgleichen
4023 SetSwgValues( rCollSet );
4024 }
4025
MakeStyle(sal_uInt16 nNo,const SvxRTFStyleType & rStyle)4026 SwTxtFmtColl* SwRTFParser::MakeStyle( sal_uInt16 nNo, const SvxRTFStyleType& rStyle)
4027 {
4028 bool bCollExist;
4029 SwTxtFmtColl* pColl = MakeColl( rStyle.sName, sal_uInt16(nNo),
4030 rStyle.nOutlineNo, bCollExist);
4031 aTxtCollTbl.Insert( nNo, pColl );
4032
4033 // in bestehendes Dok einfuegen, dann keine Ableitung usw. setzen
4034 if( bCollExist )
4035 return pColl;
4036
4037 sal_uInt16 nStyleNo = rStyle.nBasedOn;
4038 if( rStyle.bBasedOnIsSet && nStyleNo != nNo )
4039 {
4040 SvxRTFStyleType* pDerivedStyle = GetStyleTbl().Get( nStyleNo );
4041 SwTxtFmtColl* pDerivedColl = aTxtCollTbl.Get( nStyleNo );
4042 if( !pDerivedColl ) // noch nicht vorhanden, also anlegen
4043 {
4044 // ist die ueberhaupt als Style vorhanden ?
4045 pDerivedColl = pDerivedStyle
4046 ? MakeStyle( nStyleNo, *pDerivedStyle )
4047 : pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
4048 }
4049
4050 if( pColl == pDerivedColl )
4051 ((SfxItemSet&)pColl->GetAttrSet()).Put( rStyle.aAttrSet );
4052 else
4053 {
4054 pColl->SetDerivedFrom( pDerivedColl );
4055
4056 // setze die richtigen Attribute
4057 const SfxItemSet* pDerivedSet;
4058 if( pDerivedStyle )
4059 pDerivedSet = &pDerivedStyle->aAttrSet;
4060 else
4061 pDerivedSet = &pDerivedColl->GetAttrSet();
4062
4063 SetStyleAttr( (SfxItemSet&)pColl->GetAttrSet(),
4064 rStyle.aAttrSet, *pDerivedSet );
4065 }
4066 }
4067 else
4068 ((SfxItemSet&)pColl->GetAttrSet()).Put( rStyle.aAttrSet );
4069
4070
4071 nStyleNo = rStyle.nNext;
4072 if( nStyleNo != nNo )
4073 {
4074 SwTxtFmtColl* pNext = aTxtCollTbl.Get( nStyleNo );
4075 if( !pNext ) // noch nicht vorhanden, also anlegen
4076 {
4077 // ist die ueberhaupt als Style vorhanden ?
4078 SvxRTFStyleType* pMkStyle = GetStyleTbl().Get( nStyleNo );
4079 pNext = pMkStyle
4080 ? MakeStyle( nStyleNo, *pMkStyle )
4081 : pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
4082 }
4083 pColl->SetNextTxtFmtColl( *pNext );
4084 }
4085 return pColl;
4086 }
4087
MakeCharStyle(sal_uInt16 nNo,const SvxRTFStyleType & rStyle)4088 SwCharFmt* SwRTFParser::MakeCharStyle( sal_uInt16 nNo, const SvxRTFStyleType& rStyle )
4089 {
4090 int bCollExist;
4091 SwCharFmt* pFmt = MakeCharFmt( rStyle.sName, sal_uInt16(nNo), bCollExist );
4092 aCharFmtTbl.Insert( nNo, pFmt );
4093
4094 // in bestehendes Dok einfuegen, dann keine Ableitung usw. setzen
4095 if( bCollExist )
4096 return pFmt;
4097
4098 sal_uInt16 nStyleNo = rStyle.nBasedOn;
4099 if( rStyle.bBasedOnIsSet && nStyleNo != nNo )
4100 {
4101 SvxRTFStyleType* pDerivedStyle = GetStyleTbl().Get( nStyleNo );
4102 SwCharFmt* pDerivedFmt = aCharFmtTbl.Get( nStyleNo );
4103 if( !pDerivedFmt ) // noch nicht vorhanden, also anlegen
4104 {
4105 // ist die ueberhaupt als Style vorhanden ?
4106 pDerivedFmt = pDerivedStyle
4107 ? MakeCharStyle( nStyleNo, *pDerivedStyle )
4108 : pDoc->GetDfltCharFmt();
4109 }
4110
4111 if( pFmt == pDerivedFmt )
4112 ((SfxItemSet&)pFmt->GetAttrSet()).Put( rStyle.aAttrSet );
4113 else
4114 {
4115 pFmt->SetDerivedFrom( pDerivedFmt );
4116
4117 // setze die richtigen Attribute
4118 const SfxItemSet* pDerivedSet;
4119 if( pDerivedStyle )
4120 pDerivedSet = &pDerivedStyle->aAttrSet;
4121 else
4122 pDerivedSet = &pDerivedFmt->GetAttrSet();
4123
4124 SetStyleAttr( (SfxItemSet&)pFmt->GetAttrSet(),
4125 rStyle.aAttrSet, *pDerivedSet );
4126 }
4127 }
4128 else
4129 ((SfxItemSet&)pFmt->GetAttrSet()).Put( rStyle.aAttrSet );
4130
4131 return pFmt;
4132 }
4133
4134 // loesche den letzten Node (Tabelle/Fly/Ftn/..)
DelLastNode()4135 void SwRTFParser::DelLastNode()
4136 {
4137 // sollte der letze Node leer sein, dann loesche ihn
4138 // (\par heisst ja Absatzende und nicht neuer Absatz!)
4139
4140 if( !pPam->GetPoint()->nContent.GetIndex() )
4141 {
4142 sal_uLong nNodeIdx = pPam->GetPoint()->nNode.GetIndex();
4143 SwCntntNode* pCNd = pDoc->GetNodes()[ nNodeIdx ]->GetCntntNode();
4144 // paragraphs with page break information are not empty! see #117914# topic 1)
4145 if(const SfxPoolItem* pItem=&(pCNd->GetAttr( RES_PAGEDESC, sal_False)))
4146 {
4147 SwFmtPageDesc* pPageDescItem = ((SwFmtPageDesc*)pItem);
4148 if (pPageDescItem->GetPageDesc()!=NULL)
4149 return;
4150 }
4151
4152 if( pCNd && pCNd->StartOfSectionIndex()+2 <
4153 pCNd->EndOfSectionIndex() )
4154 {
4155 if( !GetAttrStack().empty() )
4156 {
4157 // Attribut Stack-Eintraege, muessen ans Ende des vorherigen
4158 // Nodes verschoben werden.
4159 sal_Bool bMove = sal_False;
4160 for( size_t n = GetAttrStack().size(); n; )
4161 {
4162 SvxRTFItemStackType* pStkEntry = (SvxRTFItemStackType*)
4163 GetAttrStack()[ --n ];
4164 if( nNodeIdx == pStkEntry->GetSttNode().GetIdx() )
4165 {
4166 if( !bMove )
4167 {
4168 pPam->Move( fnMoveBackward );
4169 bMove = sal_True;
4170 }
4171 pStkEntry->SetStartPos( SwxPosition( pPam ) );
4172 }
4173 }
4174 if( bMove )
4175 pPam->Move( fnMoveForward );
4176 }
4177 pPam->GetPoint()->nContent.Assign( 0, 0 );
4178 pPam->SetMark();
4179 pPam->DeleteMark();
4180
4181 pDoc->GetNodes().Delete( pPam->GetPoint()->nNode );
4182 }
4183 }
4184 }
4185
4186 // fuer Tokens, die im ReadAttr nicht ausgewertet werden
UnknownAttrToken(int nToken,SfxItemSet * pSet)4187 void SwRTFParser::UnknownAttrToken( int nToken, SfxItemSet* pSet )
4188 {
4189 switch( nToken )
4190 {
4191 case RTF_INTBL:
4192 {
4193 if( !pTableNode ) // Tabelle nicht mehr vorhanden ?
4194 NewTblLine(); // evt. Line copieren
4195 else
4196 {
4197 static int _do=0; //$flr See #117881# for explanation.
4198 // Crsr nicht mehr in der Tabelle ?
4199 if( !pPam->GetNode()->FindTableNode() && _do )
4200 {
4201 sal_uLong nOldPos = pPam->GetPoint()->nNode.GetIndex();
4202
4203 // dann wieder in die letzte Box setzen
4204 // (kann durch einlesen von Flys geschehen!)
4205 pPam->GetPoint()->nNode = *pTableNode->EndOfSectionNode();
4206 pPam->Move( fnMoveBackward );
4207
4208 // alle Attribute, die schon auf den nachfolgen zeigen
4209 // auf die neue Box umsetzen !!
4210 SvxRTFItemStack& rAttrStk = GetAttrStack();
4211 const SvxRTFItemStackType* pStk;
4212 for( size_t n = 0; n < rAttrStk.size(); ++n )
4213 if( ( pStk = rAttrStk[ n ])->GetSttNodeIdx() == nOldPos &&
4214 !pStk->GetSttCnt() )
4215 ((SvxRTFItemStackType*)pStk)->SetStartPos( SwxPosition( pPam ) );
4216 }
4217 }
4218 }
4219 break;
4220
4221 case RTF_PAGEBB:
4222 {
4223 pSet->Put( SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK ));
4224 }
4225 break;
4226
4227 case RTF_PGBRK:
4228 {
4229 pSet->Put( SvxFmtBreakItem( 1 == nTokenValue ?
4230 SVX_BREAK_PAGE_BOTH : SVX_BREAK_PAGE_AFTER, RES_BREAK ));
4231 }
4232 break;
4233
4234 case RTF_PGDSCNO:
4235 if( IsNewDoc() && bSwPageDesc &&
4236 sal_uInt16(nTokenValue) < pDoc->GetPageDescCnt() )
4237 {
4238 const SwPageDesc* pPgDsc = &const_cast<const SwDoc *>(pDoc)
4239 ->GetPageDesc( (sal_uInt16)nTokenValue );
4240 pDoc->InsertPoolItem( *pPam, SwFmtPageDesc( pPgDsc ), 0);
4241 }
4242 break;
4243 case RTF_CS:
4244 {
4245 SwCharFmt* pFmt = aCharFmtTbl.Get( nTokenValue );
4246 if( pFmt )
4247 pSet->Put( SwFmtCharFmt( pFmt ));
4248 }
4249 break;
4250
4251 case RTF_LS:
4252 if( -1 != nTokenValue )
4253 {
4254 if( bStyleTabValid )
4255 {
4256 // dann ist auch die ListTabelle gueltig, also suche die
4257 // enstprechende NumRule
4258 SwNumRule* pRule = GetNumRuleOfListNo( nTokenValue );
4259 if( pRule )
4260 pSet->Put( SwNumRuleItem( pRule->GetName() ));
4261
4262 if( SFX_ITEM_SET != pSet->GetItemState( FN_PARAM_NUM_LEVEL, sal_False ))
4263 pSet->Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 ));
4264 }
4265 else
4266 {
4267 // wir sind in der Style-Definitions - Phase. Der Name
4268 // wird dann spaeter umgesetzt
4269 //#117891# pSet->Put( SwNumRuleItem( String::CreateFromInt32( nTokenValue )));
4270 }
4271
4272 }
4273 break;
4274
4275 case RTF_ILVL:
4276 case RTF_SOUTLVL:
4277 {
4278 sal_uInt8 nLevel = MAXLEVEL <= nTokenValue ? MAXLEVEL - 1
4279 : sal_uInt8( nTokenValue );
4280 pSet->Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, nLevel ));
4281 }
4282 break;
4283
4284 /*
4285 case RTF_SBYS:
4286 case RTF_EXPND:
4287 case RTF_KEEP:
4288 case RTF_KEEPN:
4289 */
4290
4291 }
4292 }
4293
ReadInfo(const sal_Char * pChkForVerNo)4294 void SwRTFParser::ReadInfo( const sal_Char* pChkForVerNo )
4295 {
4296 sal_Char __READONLY_DATA aChkForVerNo[] = "StarWriter";
4297
4298 // falls nicht schon was vorgegeben wurde, setzen wir unseren Namen
4299 // rein. Wenn das im Kommentar match, wird im Parser die VersionNummer
4300 // gelesen und gesetzt
4301 if( !pChkForVerNo )
4302 pChkForVerNo = aChkForVerNo;
4303
4304 SvxRTFParser::ReadInfo( pChkForVerNo );
4305 }
4306
ReadUserProperties()4307 void SwRTFParser::ReadUserProperties()
4308 {
4309 // For now we don't support user properties but at least the parser is here.
4310 // At the moment it just swallows the tokens to prevent them being displayed
4311 int nNumOpenBrakets = 1, nToken;
4312
4313 while( nNumOpenBrakets && IsParserWorking() )
4314 {
4315 switch( nToken = GetNextToken() )
4316 {
4317 case '}':
4318 --nNumOpenBrakets;
4319 break;
4320 case '{':
4321 {
4322 if( RTF_IGNOREFLAG != GetNextToken() )
4323 nToken = SkipToken( -1 );
4324 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
4325 nToken = SkipToken( -2 );
4326 else
4327 {
4328 // gleich herausfiltern
4329 ReadUnknownData();
4330 nToken = GetNextToken();
4331 if( '}' != nToken )
4332 eState = SVPAR_ERROR;
4333 break;
4334 }
4335 ++nNumOpenBrakets;
4336 }
4337 break;
4338
4339 case RTF_PROPNAME:
4340 SkipGroup();
4341 break;
4342
4343 case RTF_PROPTYPE:
4344 break;
4345
4346 case RTF_STATICVAL:
4347 SkipGroup();
4348 break;
4349
4350 // default:
4351 }
4352 }
4353
4354 SkipToken( -1 );
4355 }
4356
4357
4358 #ifdef USED
SaveState(int nToken)4359 void SwRTFParser::SaveState( int nToken )
4360 {
4361 SvxRTFParser::SaveState( nToken );
4362 }
4363
RestoreState()4364 void SwRTFParser::RestoreState()
4365 {
4366 SvxRTFParser::RestoreState();
4367 }
4368 #endif
4369
4370 /* */
4371
BookmarkPosition(const SwPaM & rPaM)4372 BookmarkPosition::BookmarkPosition(const SwPaM &rPaM)
4373 : maMkNode(rPaM.GetMark()->nNode),
4374 mnMkCntnt(rPaM.GetMark()->nContent.GetIndex())
4375 {
4376 }
4377
BookmarkPosition(const BookmarkPosition & rEntry)4378 BookmarkPosition::BookmarkPosition(const BookmarkPosition &rEntry)
4379 : maMkNode(rEntry.maMkNode), mnMkCntnt(rEntry.mnMkCntnt)
4380 {
4381 }
4382
operator ==(const BookmarkPosition rhs)4383 bool BookmarkPosition::operator==(const BookmarkPosition rhs)
4384 {
4385 return(maMkNode.GetIndex() == rhs.maMkNode.GetIndex() && mnMkCntnt == rhs.mnMkCntnt);
4386 }
4387
GetIdx() const4388 sal_uLong SwNodeIdx::GetIdx() const
4389 {
4390 return aIdx.GetIndex();
4391 }
4392
Clone() const4393 SvxNodeIdx* SwNodeIdx::Clone() const
4394 {
4395 return new SwNodeIdx( aIdx );
4396 }
4397
Clone() const4398 SvxPosition* SwxPosition::Clone() const
4399 {
4400 return new SwxPosition( pPam );
4401 }
4402
MakeNodeIdx() const4403 SvxNodeIdx* SwxPosition::MakeNodeIdx() const
4404 {
4405 return new SwNodeIdx( pPam->GetPoint()->nNode );
4406 }
4407
GetNodeIdx() const4408 sal_uLong SwxPosition::GetNodeIdx() const
4409 {
4410 return pPam->GetPoint()->nNode.GetIndex();
4411 }
4412
GetCntIdx() const4413 xub_StrLen SwxPosition::GetCntIdx() const
4414 {
4415 return pPam->GetPoint()->nContent.GetIndex();
4416 }
4417
4418 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
4419